Chciałbym móc przewidzieć, czy operacja DELETE spowoduje naruszenie ograniczenia, bez faktycznego wykonania operacji usuwania.
Jakie są moje opcje? Czy istnieje prosty sposób na wykonanie „próbnego uruchomienia” USUŃ?
Chciałbym móc przewidzieć, czy operacja DELETE spowoduje naruszenie ograniczenia, bez faktycznego wykonania operacji usuwania.
Jakie są moje opcje? Czy istnieje prosty sposób na wykonanie „próbnego uruchomienia” USUŃ?
Odpowiedzi:
Jeśli Twoim celem jest przetworzenie wszystkich usunięć tylko wtedy, gdy wszystkie zakończą się powodzeniem, dlaczego nie użyć po prostu TRY / CATCH:
BEGIN TRANSACTION;
BEGIN TRY
DELETE #1;
DELETE #2;
DELETE #3;
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH
Jeśli celem jest umożliwienie pomyślnego usunięcia wszystkich sukcesów, nawet jeśli jedno lub więcej zakończy się niepowodzeniem, możesz użyć pojedynczej TRY / CATCH, np.
BEGIN TRY
DELETE #1;
END TRY
BEGIN CATCH
PRINT 1;
END CATCH
BEGIN TRY
DELETE #2;
END TRY
BEGIN CATCH
PRINT 1;
END CATCH
Jedną z opcji jest rozpoczęcie transakcji, uruchomienie operacji usuwania, a następnie zawsze wycofywanie:
begin tran
delete Table1 where col1 = 1
-- Test whether it is there
select * from Table1 where col1 = 1
rollback tran
-- Confirm that it is still there
select * from Table1 where col1 = 1
Chciałbym ulepszyć rozwiązanie dostarczone przez Aarona Bertranda z pewnym kodem, na wypadek gdybyś chciał spróbować dodać dowolny element tabeli, zarządzanie wyjątkami do ignorowania kończy się niepowodzeniem lub zatrzymanie procesu po błędach.
Ten wybierze rekordy z tabeli, a następnie spróbuje je usunąć bez wyjątków:
DECLARE @MaxErrors INT
SET @MaxErrors = 5; // Setting 0 will stop process after the first error!
SELECT
[Id]
, ROW_NUMBER() OVER (ORDER BY Id ASC) AS [Index]
INTO #DeletingItems
FROM myTable
DECLARE @Current INT, @Max INT, @Id INT, @TotErrors INT
SELECT
@Current = 1
, @TotErrors = 0
, @Max = MAX([Index])
FROM #DeletingTable
WHILE @Current <= @Max
BEGIN
SELECT
@Id = [Id]
FROM #DeletingItems
WHERE
[Index] = @Index;
BEGIN TRANSACTION;
BEGIN TRY
DELETE FROM myTable WHERE [Id] = @Id;
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
SET @TotErrors = @TotErrors + 1;
IF @TotErrors > @MaxErrors
BREAK;
END CATCH
SET @Current = @Current + 1;
END