2010-06-23 2 views
2

je le déclencheur suivant:SQL Server Supprimer Trigger Pour mettre à jour plusieurs colonnes dans le tableau même

CREATE TRIGGER Users_Delete 
    ON Users 
    AFTER DELETE 
AS 
BEGIN 

    SET NOCOUNT ON; 

    -- Patients 
    UPDATE Patients SET ModifiedByID=NULL WHERE ModifiedByID=ID; 
    UPDATE Patients SET CreatedByID=NULL WHERE CreatedByID=ID; 
    UPDATE Patients SET DeletedByID=NULL WHERE DeletedByID=ID; 

END 

Je me demandais s'il y a un moyen de « combiner » ces trois déclarations de mise à jour dans quelque chose qui serait comme ce qui suit :

UPDATE Patients SET 
(ModifiedByID=NULL WHERE ModifiedByID=ID) OR 
(CreatedByID=NULL WHERE CreatedByID=ID) OR 
(DeletedByID=NULL WHERE DeletedByID=ID); 

Je voudrais vraiment avoir une seule instruction pour augmenter les performances.

La raison pour laquelle j'utilise la gâchette plutôt que sur ON DELETE pour le FOREIGN KEY est parce que je reçois l'erreur ayant plus d'un ON DELETE provoque l'erreur suivante:

Introducing FOREIGN KEY constraint 'FK_Patients_Users_Deleted' on table 'Patients' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

EDIT: serait-il bon avoir des index sur toutes les colonnes ModifiedByID, CreatedByID, DeletedByID? La suppression d'un utilisateur sera bien sûr rare, alors cela vaut-il la peine d'ajouter des index à 3 colonnes?

+2

Ce qui me dérange, c'est que vous modifiez ces données du tout. Il est préférable d'inactiver un utilisateur plutôt que d'en supprimer un qui a des enregistrements enfants associés à celui-ci. Maintenant, vous ne serez pas en mesure de dire qui a créé l'enregistrement qui est probablement d'une certaine importance, surtout si l'utilisateur a été renvoyé pour des raisons de performance. – HLGEM

+0

C'est en fait un point très valable. Je vais prendre cela en considération. – TheCloudlessSky

Répondre

1

Quelque chose comme ça?

UPDATE Patients SET 
ModifiedByID = CASE WHEN ModifiedByID=ID THEN Null ELSE ModifiedById END, 
CreatedByID = CASE WHEN CreatedByID=ID THEN Null ELSE CreatedById END, 
DeletedByID = CASE WHEN DeletedByID=ID THEN Null ELSE DeletedById END 
WHERE (ModifiedByID = ID OR CreatedByID = ID OR DeletedByID = ID) 
+0

Je suppose que le seul cas dans lequel vous verriez une amélioration des performances est si la table Patients est très volumineuse et que vous n'avez pas les index appropriés sur ModifiedByID, CreatedByID ou DeletedByID. Dans ce cas, la solution consiste à ajouter les index – Yellowfog

+0

Alors, pensez-vous qu'il est préférable d'utiliser les 3 instructions telles quelles avec les index sur ModifiedByID/CreatedByID/DeletedByID? – TheCloudlessSky

+0

Je soupçonne fortement que cela fera peu ou pas de différence, donc j'irais avec celui qui est plus facile à comprendre (c'est-à-dire les trois déclarations) – Yellowfog

1

Vous pouvez le faire en une seule instruction, mais ce n'est pas forcément meilleur pour les performances. Je doute vraiment que cela fonctionnera mieux cependant.

2

En ce qui concerne votre question initiale.

Pas vraiment. Je ne peux pas trouver quelque chose de mieux que

UPDATE Patients 
SET ModifiedByID= CASE WHEN ModifiedByID=ID THEN NULL ELSE ModifiedByID END, 
CreatedByID= CASE WHEN CreatedByID=ID THEN NULL ELSE CreatedByID END, 
DeletedByID= CASE WHEN DeletedByID=ID THEN NULL ELSE DeletedByID END 
WHERE 
ModifiedByID IN (SELECT ID FROM DELETED) 
OR 
CreatedByID IN (SELECT ID FROM DELETED) 
OR 
DeletedByID IN (SELECT ID FROM DELETED) 

Notez que cela gère une suppression de plusieurs lignes correctement. Il n'est pas clair à partir de ce que vous avez posté si votre déclencheur actuel fait.

+0

Point important, de nombreuses personnes codent sur un seul enregistrement et échouent à la suite d'actions sur plusieurs lignes. –

Questions connexes