J'aimerais pouvoir prédire si un DELETE se heurtera à une violation de contrainte, sans réellement effectuer la suppression.
Quelles sont mes options pour ce faire? Existe-t-il un moyen simple de faire un "essai à sec" d'une SUPPRESSION?
J'aimerais pouvoir prédire si un DELETE se heurtera à une violation de contrainte, sans réellement effectuer la suppression.
Quelles sont mes options pour ce faire? Existe-t-il un moyen simple de faire un "essai à sec" d'une SUPPRESSION?
Réponses:
Si votre objectif est de traiter toutes les suppressions uniquement si elles réussissent toutes, pourquoi ne pas simplement utiliser TRY / CATCH:
BEGIN TRANSACTION;
BEGIN TRY
DELETE #1;
DELETE #2;
DELETE #3;
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH
Si l'objectif est de permettre à toutes les suppressions réussies de réussir même si une ou plusieurs échouent, alors vous pouvez utiliser un TRY / CATCH individuel, par exemple
BEGIN TRY
DELETE #1;
END TRY
BEGIN CATCH
PRINT 1;
END CATCH
BEGIN TRY
DELETE #2;
END TRY
BEGIN CATCH
PRINT 1;
END CATCH
Une option consiste à commencer une transaction, exécuter votre suppression, puis toujours annuler:
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
Je voudrais améliorer la solution fournie par Aaron Bertrand avec du code, au cas où vous voudriez ajouter un élément d'une table, gérer les exceptions pour ignorer les échecs ou arrêter le processus après les erreurs.
Celui-ci sélectionnera les enregistrements de la table puis essaiera de les supprimer sans exception:
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