Meilleur auteur de réponses
TRIGGER AFTER/FOR DELETE Problem

Question
-
Salut, actuellement je travaille sur mon projet de fin d'étude et j'ai un problème avec l'utilisation des trigger.
J'ai deux Table: TableX et TableXHistory ou j'ai besoin que le TRIGGER fait une insertion des données de la Table TableX vers TableXHistroy et cela a chaque suppression.
Sachant que mes Tables: TableX et TableXHistory ont une clé primaire composée.
Voici le code du trigger:
CREATE TRIGGER MyTrigger ON dbo.Table FOR DELETE /*J'ai même essayé avec AFTER DELETE aussi et j'ai pas trouver de différence*/ AS BEGIN DECLARE @Col1 NVARCHAR(50), @Col2 NVARCHAR(50), @Col3 NVARCHAR(50) SELECT @Col1 = Col1 , @Col2 = Col2, @Col3= Col13 FROM Deleted INSERT INTO dbo.TableXHistory VALUES(@Col1,@Col2,@Col3) END
Bon sur ma table: TableX j'execute une requête qui va supprimer +de 1000lignes, et je veux que le trigger les insert dans la table TableXHistroy mais j'ai qu'une seule ligne qui est inséré.
Tandis que si je fait un SELECT et je récupère les lignes a supprimer et je fait un DELETE pour chaqu'une, le TRIGGER fonctionne correctement et cela prend beaucoup de temps.
Info:
WINDOWS 8, SQLSERVER 2012 (Express), VISUAL STUDIO 2012
Merci d'avance :)
- Déplacé Naomi N mardi 16 avril 2013 16:04 Better answer can be here
Réponses
-
A common misconception is that the trigger fires for each row. If that were true, your code would work fine. However the trigger fires once for the DELETE statement, meaning only one trigger execution for 1 row, but also only one trigger execution for 1000 rows.
So your code is using variables that can only hold a single value. What you should do inside your procedure is code for an unknown number of rows. The following should work:
INSERT INTO dbo.TableXHistory (Col1, Col2, Col3) SELECT Col1, Col2, Col3 FROM deleted
This INSERT will receive all of the rows that you SELECT from deleted, whether 1 or 1000. Does that make sense to you?
RLF
PS Google Translate: Une idée fausse commune est que le déclencheur est lancé pour chaque ligne. Si cela était vrai, votre code va fonctionner très bien. Toutefois, le déclencheur se déclenche une fois pour l'instruction DELETE, ce qui signifie une seule exécution du déclencheur pour 1 rangée, mais aussi une seule exécution du déclencheur pour 1000 lignes.
Ainsi, votre code utilise des variables qui ne peut contenir qu'une seule valeur. Ce que vous devez faire dans votre procédure est un code pour un nombre indéterminé de lignes. Ce qui suit devrait fonctionner:Cet insert recevrez toutes les lignes que vous sélectionnez supprimé, si 1 ou 1000. Est-ce logique pour vous?
Toutes les réponses
-
A common misconception is that the trigger fires for each row. If that were true, your code would work fine. However the trigger fires once for the DELETE statement, meaning only one trigger execution for 1 row, but also only one trigger execution for 1000 rows.
So your code is using variables that can only hold a single value. What you should do inside your procedure is code for an unknown number of rows. The following should work:
INSERT INTO dbo.TableXHistory (Col1, Col2, Col3) SELECT Col1, Col2, Col3 FROM deleted
This INSERT will receive all of the rows that you SELECT from deleted, whether 1 or 1000. Does that make sense to you?
RLF
PS Google Translate: Une idée fausse commune est que le déclencheur est lancé pour chaque ligne. Si cela était vrai, votre code va fonctionner très bien. Toutefois, le déclencheur se déclenche une fois pour l'instruction DELETE, ce qui signifie une seule exécution du déclencheur pour 1 rangée, mais aussi une seule exécution du déclencheur pour 1000 lignes.
Ainsi, votre code utilise des variables qui ne peut contenir qu'une seule valeur. Ce que vous devez faire dans votre procédure est un code pour un nombre indéterminé de lignes. Ce qui suit devrait fonctionner:Cet insert recevrez toutes les lignes que vous sélectionnez supprimé, si 1 ou 1000. Est-ce logique pour vous?
-
-
Bonjour,
Est-ce que vous avez testé les solutions proposées ? Merci de partager avec nous les résultats, afin que d'autres personnes avec le même problème puissent profiter de cette solution.
Cordialement,
-
-
Bonjour;
après quelques mois je passe sur la question, une autre solution pourrais résoudre le problème (que j'utilise souvent).
l'idée est que dans la requête dans le programme client on peut spécifié si le résultat de la suppression va être affecter à une table
DELETE "Nom_Table"
OUTPUT DELETED.* into "Nom_Table_Cible"
where ..... (clause where de la suppression)