Я хотів би мати можливість передбачити, чи буде DELETE наштовхнутися на порушення обмеження, не виконуючи фактично видалення.
Які мої варіанти зробити це? Чи є простий спосіб зробити «сухий пробіг» DELETE?
Я хотів би мати можливість передбачити, чи буде DELETE наштовхнутися на порушення обмеження, не виконуючи фактично видалення.
Які мої варіанти зробити це? Чи є простий спосіб зробити «сухий пробіг» DELETE?
Відповіді:
Якщо ваша мета полягає в обробці всіх видалених файлів, лише якщо всі вони досягли успіху, чому б не просто використовувати TRY / CATCH:
BEGIN TRANSACTION;
BEGIN TRY
DELETE #1;
DELETE #2;
DELETE #3;
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH
Якщо мета полягає в тому, щоб дозволити всім успішним делетам досягти успіху, навіть якщо один або декілька не вдасться, тоді ви можете використовувати індивідуальний 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
Один із варіантів - почати транзакцію, запустити видалення, а потім завжди відкатати:
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
Я хотів би вдосконалити рішення, надане Аароном Бертран, деяким кодом, на випадок, якщо ви хочете спробувати додати будь-який елемент таблиці, керуючи винятками, щоб ігнорувати помилки, а також зупинити помилки після процесу.
Цей обере записи із таблиці, а потім намагається видалити їх без винятку:
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