Comment puis-je obtenir un déclencheur sur chaque ligne insérée lors d'une INSERTION DANS la Table ( ... ) SELECT * from Table2?
J'ai essayé d'éviter l'utilisation d'un curseur dans ce cas particulier, juste parce que je n'aime pas les compromis, et il arrive, je m'y suis fait à l'aide de déclencheurs ressembler à la bonne marche de l'action, de toute façon.
Une procédure stockée insère un enregistrement à partir d'un mélange complexe de clauses, à l'aide d'un déclencheur d'insertion-je envoyer un e-mail à l'utilisateur cible de leur dire de la visite d'un site. C'est facile et fonctionne très bien.
Cependant, une autre procédure consiste à exécuter tous les soirs, et de redistribuer tous les non-visualisation des enregistrements. La façon dont je le faisais c'était de faire un autre insert basé sur un select sur un champ de date à partir de quand il a été affecté. À savoir:
INSERT INTO Table (ID, User, AssignDate, LastActionDate)
SELECT
ID
,User
,GETDATE() [AssignDate]
,GETDATE() [LastModifiedDate]
FROM Table2
/*snip*/
Le déclencheur fonctionne sur les différents inserts, mais l'instruction select ci-dessus ne fonctionne que sur la dernière ligne insérée. Est-il un moyen de contourner ce problème? Il ruine toute chose!
Modifier (code du déclencheur):
ALTER TRIGGER dbo.Notify
ON dbo.Table
AFTER INSERT
AS
BEGIN
DECLARE @EmailSender varchar(50)='Sender Profile'
DECLARE @Identity int
DECLARE @User varchar(20)
DECLARE @Subject varchar(50)
SET @Identity=@@Identity
SELECT @User=User, @Subject='(' + CONVERT(varchar,@Identity) + ')!'
FROM Table
WHERE
idNum=@Identity
exec msdb.dbo.sp_send_dbmail
@profile_name=@EmailSender,
@recipients=@User
@subject=@Subject,
@body='//etc'
END
inserted
et/ou deleted
. Habituellement, cela peut être fait sans avoir recours à des curseurs. Mais nous aurions besoin de voir plus de code pour informer - tout ce que vous avez montré pour le moment est un standard de l'instruction insert.Ajouté dans le code du déclencheur.
Je pense que vous aurez besoin d'un curseur pour cela. Je ne pense pas qu'il y a quelque chose de prévu pour vous permettre d'insérer de multiples e-mails en une seule fois.
Vous ne devez pas utiliser @@identity, vous utilisez le champ id de l'inséré pseudotable. En fait, vous avez presque ne faut jamais utiliser @@identity dans tout le processus comme il peut renvoyer le worng résultats et le désordre de notre intégrité des données.
Bauer - Donc, si un 100 lignes sont insérées dans un seul énoncé, vous voulez 100 e-mails envoyés? Je suis désolé pour ces bénéficiaires.
OriginalL'auteur C Bauer | 2011-04-27
Vous devez vous connecter pour publier un commentaire.
Le déclencheur d'insertion est appelée une fois pour des insertions, mais sur le déclencheur, vous pouvez utiliser le
inserted
table pour obtenir toutes les lignes insérées.Alors, imaginez que vous avez un déclencheur d'insertion comme celui-ci, qui enregistre toutes les lignes insérées dans
table
Avec ce déclencheur, lorsque vous effectuez un bulk insert sur
table
, letableLog
est rempli avec le même nombre de lignes qui ont été insérées àtable
Pour vous déclencheur spécifique, car vous avez besoin pour appeler une procédure stockée pour chaque ligne, vous devez utiliser un curseur:
Je n'ai pas testé, mais devrait fonctionner
Soin d'expliquer?
Juste un très mineur commentaire - dans le cas où insensible exemple, vous aurez besoin pour sélectionner un autre nom pour le curseur de 'curseur'
OriginalL'auteur Jose Rui Santos
Si vous envoyez un email, je ne voudrais pas le faire à partir d'un déclencheur. Voulez-vous vraiment les gens pour ne pas être en mesure d'insérer des enregistrements dans la mesure où le serveur de messagerie est en panne?
Il est généralement préférable d'insérer les enregistrements à une table de la gâchette et puis avoir un emploi qui envoie les e-mails qui s'exécute chaque minute ou deux, et les mises à jour les statuts d'emails envoyés et ajoute l'envoyé datetime à la table lors de chaque enregistrement est envoyé. Ce n'est pas seulement vous permet d'insérer des enregistrements lorsque les e-mails sont à la baisse, il se déplace de la boucle d'envoyer chaque e-mail à une table, les utilisateurs n'y ont pas accès (et, donc, de tout retard dans le traitement de nombreux dossiers n'affecteront que les nouveaux utilisateurs n'est pas quelqu'un d'autre) et il vous permet de voir l'historique d'lors de l'envoi de l'e-mail qui permet, quand les gens demandent pourquoi ils n'avaient pas le faire. Vous pouvez également enregistrer dans la table si l'email n'a pas pu envoyer pour aider à identifier les mauvaises adresses e-mail.
Assez dur à envoyer des e-mails à une seule personne à la fois, sans un curseur ou une boucle. au moins si ils sont dans une autre table, ils ne seront pas interférer avec les opérations normales.
Bauer,@HLGEM - Ce serait préférable à l'exécution d'un curseur dans un déclencheur. En outre, il vous permet de désactiver les notifications sur les machines de développement en écrivant dans les notifications de la table, mais la désactivation de l'envoi de courrier électronique proc. Cette approche permettrait également d'externaliser l'envoi de courrier électronique à un service si jamais désiré.
OriginalL'auteur HLGEM