J'ai un déclencheur de table sur UPDATE et INSERT qui ajoute une ligne à une autre table. Il n'a besoin d'ajouter une ligne que si l'une des quatre colonnes est modifiée. J'ai essayé d'utiliser IF UPDATE (col) pour tester les changements mais il a un angle mort. Il teste seulement qu'une certaine valeur est entrée. J'ai besoin d'approfondir, j'ai besoin de comparer les anciennes et les nouvelles valeurs pour voir qu'un vrai changement s'est produit. Il doit fonctionner avec INSERT et UPDATE.
Dans le cas d'une MISE À JOUR, c'est facile car les tables insérées et supprimées ont des valeurs que je peux comparer dans le déclencheur. Cependant, pour INSERT, seule la table d'insertion a des valeurs. Parce que j'ai besoin de tout cela dans le même déclencheur, comment gérer ce cas INSERT?
Voici le script du déclencheur que je souhaite modifier:
ALTER TRIGGER [dbo].[trATPerson_alter]
ON [mydb].[dbo].[AT_Person]
AFTER INSERT,UPDATE
AS
BEGIN
SET NOCOUNT ON;
-- Not all updates require a push
IF (UPDATE([First_Name]) OR UPDATE([Last_Name]) OR UPDATE([JobCode]) OR UPDATE([Inactive]))
BEGIN
INSERT INTO [mydb].[dbo].[AT_Person_To_Push] (
[Facility],
[VendorID],
[Person_code],
[First_Name],
[Last_Name],
[JobCode],
[Alink],
[Inactive]
)
SELECT [Facility],
[VendorID],
[Person_code],
[First_Name],
[Last_Name],
[JobCode],
[Alink],
[Inactive]
FROM inserted
END
END
Réponses:
Vous pouvez gérer à la fois INSERT et UPDATE avec un opérateur set EXCEPT. Les EXISTS n'évalueront à VRAI que si c'est juste un INSERT, ou si c'est une MISE À JOUR avec des valeurs différentes pour l'une de ces colonnes.
la source
EXISTS
vérifie que toute ligne a changé. Si vous conservez l'insertion de la question, vous enregistrerez alors toutes les lignes mises à jour lorsqu'une seule change de manière significative.Dans le cas où une mise à jour peut affecter plusieurs lignes, vous devez vous protéger contre deux choses:
AT_Person_To_Push
. Si 5 lignes sont mises à jour, mais seulement 2 sont mises à jour d'une manière qui nous tient à cœur, alors nous devons traiter uniquement les 2 lignes pertinentes.Voici comment je le gérerais:
inserted
àdeleted
, carinserted
aura des lignes pour les insertions et les mises à jour tandis quedeleted
n'aura que des lignes pour les mises à jour.EXISTS
avecEXCEPT
pour rechercher les lignes où lesinserted
valeurs diffèrent desdeleted
valeurs. Vous ne pouvez pas l'utiliseri.First_Name != d.First_Name OR i.Last_Name != d.Last_Name...
car la table supprimée sera vide (et LEFT JOIN renverra des valeurs nulles) lorsque le déclencheur gère un INSERT.AT_Person_To_Push
.la source
Essaye ça,
la source