Je dois construire la logique suivante sur une paire de tables SQL. Voici la structure de la table de base:Déclencheur SQL avec mises à jour conditionnelles
TABLE [dbo].[Email](
[IssueId] [int] NOT NULL,
[NoErrors] [int] NOT NULL,
[EmailBody] [nvarchar](max) NULL,
...
)
TABLE [dbo].[Inclusion](
[InclusionId] [int] IDENTITY(1,1) NOT NULL,
[IssueId] [int] NOT NULL,
...
)
La relation principale pour les deux tables est une table [d'émission] sur le terrain IssueId. Chaque enregistrement de problème n'a qu'une seule table de courrier électronique associée, mais zéro à plusieurs enregistrements d'inclusion.
Ce que je veux arriver est ce ...
Si un enregistrement d'inclusion est supprimé et il a été le dernier enregistrement d'inclusion associée à la question, alors je veux régler les Email.NoErrors à -1. Si d'autres inclusions existent (après la suppression), je souhaite laisser le champ Email.NoErrors 'tel quel'.
J'ai écrit le déclencheur suivant qui semble fonctionner:
ALTER TRIGGER [dbo].[trg_Inclusion_Delete]
ON [dbo].[Inclusion]
AFTER DELETE
AS
BEGIN
SET NOCOUNT ON;
UPDATE Email
SET NoErrors = CASE
WHEN EXISTS (
SELECT * FROM Inclusion
WHERE IssueId = DELETED.IssueId
)
THEN NoErrors -- Leave existing value
ELSE
(-1)
END
FROM DELETED
WHERE Email.IssueId = DELETED.IssueId
END
Il y a deux choses que je connais assez pour inquiéter. Tout d'abord, le déclencheur semble inefficace car il met toujours à jour le Email.NoErrors classé, même si ce n'est pas obligatoire. Deuxièmement, je suis conscient que la table de référence DELETED peut contenir plus d'un enregistrement mais je ne suis pas sûr que mon script le gère correctement - mais je ne le crois pas.
Tout conseil/direction serait grandement apprécié.
MISE À JOUR
Voici le code final que j'ai fini avec:
ALTER TRIGGER [dbo].[trg_Inclusion_Delete]
ON [dbo].[Inclusion] AFTER DELETE
AS
IF @@ROWCOUNT = 1
BEGIN
UPDATE Issue
SET NoEmailErrors = -1
FROM DELETED
WHERE (
Issue.IssueId = DELETED.IssueId
AND Issue.NoEmailErrors != -1
AND NOT EXISTS (
SELECT *
FROM Inclusion
WHERE Inclusion.IssueId = DELETED.IssueId
)
)
END
ELSE
BEGIN
UPDATE Issue
SET NoEmailErrors = -1
FROM DELETED
WHERE (
Issue.IssueId IN (
SELECT IssueId FROM DELETED
)
AND Issue.NoEmailErrors != -1
AND NOT EXISTS (
SELECT *
FROM Inclusion
WHERE Inclusion.IssueId = DELETED.IssueId
)
)
END
Merci Eric, votre code est beaucoup plus propre. J'ai également trouvé le lien suivant http://msdn.microsoft.com/en-us/library/ms190752.aspx qui je pense est pertinent à ce que j'essaye de faire. J'ai mis à jour mon message original pour inclure le nouveau script – Neilski