実際に削除を実行せずに、DELETEが制約違反に遭遇するかどうかを予測できるようにしたいと思います。
これを行うための私のオプションは何ですか? DELETEの「ドライラン」を実行する簡単な方法はありますか?
すべての削除が成功した場合にのみすべての削除を処理することが目標である場合は、TRY/CATCHを使用しないでください。
BEGIN TRANSACTION;
BEGIN TRY
DELETE #1;
DELETE #2;
DELETE #3;
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH
1つ以上が失敗してもすべての成功した削除を成功させることが目的である場合は、個別のTRY/CATCHを使用できます。
BEGIN TRY
DELETE #1;
END TRY
BEGIN CATCH
PRINT 1;
END CATCH
BEGIN TRY
DELETE #2;
END TRY
BEGIN CATCH
PRINT 1;
END CATCH
1つのオプションは、トランザクションを開始し、削除を実行してから、常にロールバックすることです。
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
Aaron Bertrandが提供するソリューションをいくつかのコードで改善したいと思います。テーブルの要素を追加したり、例外を管理して失敗を無視したり、エラー後にプロセスを停止したりする場合です。
これはテーブルからレコードを選択し、例外なくそれらを削除しようとします:
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