Saya ingin dapat memprediksi apakah DELETE akan mengalami pelanggaran kendala, tanpa benar-benar melakukan penghapusan.
Apa pilihan saya untuk melakukan ini? Apakah ada cara sederhana untuk melakukan "dry run" dari DELETE?
Saya ingin dapat memprediksi apakah DELETE akan mengalami pelanggaran kendala, tanpa benar-benar melakukan penghapusan.
Apa pilihan saya untuk melakukan ini? Apakah ada cara sederhana untuk melakukan "dry run" dari DELETE?
Jawaban:
Jika tujuan Anda adalah untuk memproses semua penghapusan hanya jika semuanya berhasil, mengapa tidak menggunakan TRY / CATCH:
BEGIN TRANSACTION;
BEGIN TRY
DELETE #1;
DELETE #2;
DELETE #3;
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH
Jika tujuannya adalah untuk memungkinkan semua penghapusan yang berhasil berhasil bahkan jika satu atau lebih akan gagal, maka Anda dapat menggunakan TRY / CATCH individu, misalnya
BEGIN TRY
DELETE #1;
END TRY
BEGIN CATCH
PRINT 1;
END CATCH
BEGIN TRY
DELETE #2;
END TRY
BEGIN CATCH
PRINT 1;
END CATCH
Salah satu opsi adalah memulai transaksi, menjalankan penghapusan Anda, dan kemudian selalu mengembalikan:
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
Saya ingin meningkatkan solusi yang disediakan oleh Aaron Bertrand dengan beberapa kode, jika Anda ingin mencoba menambahkan elemen tabel, mengelola pengecualian untuk mengabaikan gagal atau juga menghentikan proses setelah kesalahan.
Yang ini akan memilih catatan dari tabel dan kemudian mencoba untuk menghapusnya tanpa kecuali:
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