J'ai une table déclencheur 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
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.
IF EXISTS (
SELECT First_Name, Last_Name, JobCoe, Inactive FROM inserted
EXCEPT
SELECT First_Name, Last_Name, JobCoe, Inactive FROM deleted
)
BEGIN...
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
, car inserted
aura des lignes pour les insertions et les mises à jour tandis que deleted
n'aura que des lignes pour les mises à jour.EXISTS
avec EXCEPT
pour rechercher les lignes où les valeurs inserted
diffèrent des valeurs deleted
. Vous ne pouvez pas utiliser i.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
.ALTER TRIGGER [dbo].[trATPerson_alter]
ON [mydb].[dbo].[AT_Person]
AFTER INSERT,UPDATE
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [mydb].[dbo].[AT_Person_To_Push] (
[Facility],
[VendorID],
[Person_code],
[First_Name],
[Last_Name],
[JobCode],
[Alink],
[Inactive]
)
SELECT i.[Facility],
i.[VendorID],
i.[Person_code],
i.[First_Name],
i.[Last_Name],
i.[JobCode],
i.[Alink],
i.[Inactive]
FROM inserted i
LEFT JOIN deleted d
ON i.Person_code = d.Person_code
-- Check for changes that require a Push
WHERE EXISTS (SELECT i.[First_Name], i.[Last_Name], i.[JobCode], i.[Inactive]
EXCEPT
SELECT d.[First_Name], d.[Last_Name], d.[JobCode], d.[Inactive]);
END
Essaye ça,
Declare @Acton int=0
If exists (Select 1 from inserted)
set @Acton=1
If exists (Select 1 from deleted)
set @Acton=@Acton+2
if(@Action=1) -- Only insert
if(@Action=3) -- Only Update
begin
IF (UPDATE([First_Name]) OR UPDATE([Last_Name]) OR UPDATE([JobCode]) OR UPDATE([Inactive]))
Begin
End
end
if(@Action=2) -- Only Delete