Ich möchte vorhersagen können, ob ein DELETE auf eine Einschränkungsverletzung stößt, ohne das Löschen tatsächlich durchzuführen.
Welche Möglichkeiten habe ich dazu? Gibt es eine einfache Möglichkeit, einen "Trockenlauf" eines DELETE durchzuführen?
Ich möchte vorhersagen können, ob ein DELETE auf eine Einschränkungsverletzung stößt, ohne das Löschen tatsächlich durchzuführen.
Welche Möglichkeiten habe ich dazu? Gibt es eine einfache Möglichkeit, einen "Trockenlauf" eines DELETE durchzuführen?
Antworten:
Wenn Sie alle Löschvorgänge nur dann verarbeiten möchten, wenn alle erfolgreich sind, verwenden Sie einfach TRY / CATCH:
BEGIN TRANSACTION;
BEGIN TRY
DELETE #1;
DELETE #2;
DELETE #3;
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH
Wenn das Ziel darin besteht, dass alle erfolgreichen Löschvorgänge erfolgreich sind, auch wenn einer oder mehrere fehlschlagen, können Sie einzelne TRY / CATCH verwenden, z
BEGIN TRY
DELETE #1;
END TRY
BEGIN CATCH
PRINT 1;
END CATCH
BEGIN TRY
DELETE #2;
END TRY
BEGIN CATCH
PRINT 1;
END CATCH
Eine Möglichkeit besteht darin, eine Transaktion zu starten, das Löschen auszuführen und dann immer ein Rollback durchzuführen:
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
Ich möchte die von Aaron Bertrand bereitgestellte Lösung mit etwas Code verbessern, falls Sie versuchen möchten, ein Element einer Tabelle hinzuzufügen, die Ausnahmen zu ignorieren, um Fehler zu ignorieren, oder den Prozess nach Fehlern zu stoppen.
Dieser wählt die Datensätze aus der Tabelle aus und versucht dann, sie ohne Ausnahmen zu löschen:
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