Я хотел бы иметь возможность предсказать, приведет ли 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