Eu gostaria de poder prever se um DELETE terá uma violação de restrição, sem realmente executar a exclusão.
Quais são as minhas opções para fazer isso? Existe uma maneira simples de fazer uma "execução a seco" de um DELETE?
Eu gostaria de poder prever se um DELETE terá uma violação de restrição, sem realmente executar a exclusão.
Quais são as minhas opções para fazer isso? Existe uma maneira simples de fazer uma "execução a seco" de um DELETE?
Respostas:
Se seu objetivo é processar todas as exclusões apenas se todas tiverem êxito, por que não usar TRY / CATCH:
BEGIN TRANSACTION;
BEGIN TRY
DELETE #1;
DELETE #2;
DELETE #3;
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH
Se o objetivo é permitir que todas as exclusões bem-sucedidas sejam bem-sucedidas, mesmo que uma ou mais falhe, você pode usar TENTAR / PEGAR individualmente, por exemplo
BEGIN TRY
DELETE #1;
END TRY
BEGIN CATCH
PRINT 1;
END CATCH
BEGIN TRY
DELETE #2;
END TRY
BEGIN CATCH
PRINT 1;
END CATCH
Uma opção é iniciar uma transação, executar sua exclusão e sempre reverter:
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
Gostaria de melhorar a solução fornecida por Aaron Bertrand com algum código, caso você queira adicionar qualquer elemento de uma tabela, gerenciando as exceções para ignorar falhas ou também interromper o processo após erros.
Este selecionará os registros da tabela e tentará excluí-los sem exceções:
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