问题 在SQL Server中创建触发器


当我想使用SQL Server 2008 R2的预定义“CREATE TRIGGER”创建触发器时,我迷路了。你能不能给我一个直接的SQL语句,我可以用来创建一个触发器,并告诉我如何定义AFTER,BEFORE等等?

另外,如何知道行UPDATED / INSERTED / DELETED,并使用它们的列值在触发器内执行操作?


1479
2017-07-29 02:05


起源

@john:该产品被称为“SQL Server”,而不是“MSSQL”。 “MSSQL”很容易与“MySQL”混淆。另外,在询问SQL Server问题时,我建议您使用“sql-server”标记。 “sql”是关于SQL语言的一般问题。 - John Saunders
好的,谢谢你的说明。会那样做。 - johnshaddad
您的问题仅仅是关于如何定义触发器,还是如何编写可用于对受影响的行进行操作的触发器?如果是晚些时候,那么你应该考虑改述你的问题。 - Thomas
好的我修改了我的问题 - johnshaddad


答案:


数据库是面向集合的,触发器也不例外。执行给定操作时该触发器将触发,该操作可能会影响多行。因此,问题 "Say I want to know the Primary Key of that row" 用词不当。可能会插入多行。

SQL Server为名为的AFTER触发器提供了两个特殊表 inserted 和 deleted 表示由操作插入或删除的行,其结构与受影响的表格相同。更新触发器可能会填充两者 inserted 和 deleted 而插入触发器只会填充 inserted 表。

来自评论:

但是电子邮件收件人将根据第二个表中的值来决定,其中外键ID位于第一个表中(具有触发器的表)

这个问题的答案是使用 inserted table(再次,你必须假设可能有多行)循环遍历行并发送电子邮件。但是,我建议不要将电子邮件逻辑放在触发器中。相反,我建议将该逻辑放在存储过程中并从中发送您的电子邮件。

以供参考: 创建触发器


3
2017-07-29 02:30



然后从触发器调用该过程?你是这个意思吗?但是不是sql邮件系统程序足以在触发器中处理它吗?或者我应该创建一个调用该系统过程的过程,然后在触发器中调用此过程? - johnshaddad
@johnshaddad - 不,我不会通过触发器进行电子邮件操作。相反,我会让你的调用代码使用存储的proc而不是直接对表进行操作。 - Thomas
当你说“可能插入多行”时。是不是多次触发扳机?或者怎么样?你能解释我在这种情况下如何循环吗? - johnshaddad
@johnshaddad - 每个语句或操作触发一次触发器。例如,假设您有一个查询 Insert Table(...) Select ... From OtherTable 插入100行。触发器只会触发一次。特别的 inserted table将有100行,您可以使用类似游标的东西循环或可以在其他SQL语句中使用(例如, Insert LogTable(...) Select ... From inserted)。 - Thomas
@johnshaddad - 现在,如果不是单一的话 Insert Table(...) Select ... From OtherTable 调用,假设您执行100 Insert语句,每次插入一行。每个语句都会触发一次触发器 inserted table每次触发时都会包含一行。但是,在编写触发器时,您必须假设有人可以使用将影响多行的set操作插入,更新或删除表。 - Thomas


基本语法是

CREATE TRIGGER YourTriggerName ON dbo.YourTable
FOR|AFTER INSERT, UPDATE, DELETE
AS
BEGIN
     /*Put what ever you want here*/
     UPDATE AnotherTable
          SET SomeColumn = AnotherColumn
     FROM inserted | deleted
END
GO

11
2017-07-29 02:32



我正在尝试这个,它在MS服务器上对我不起作用。 - Doug Hauf


触发器是基于事件的进程,在以某种方式更改表后“触发”。这将是DELETE,UPDATE,INSERT等。 BEFORE和AFTER语法将定义在事件提交之前或之后是否运行触发器。

那是短版本。查看 MSDN


2
2017-07-29 02:07



是的,我熟悉MySQL上的触发器但不熟悉MSSQL,所以我认为有不同的实现方式。谢谢! - johnshaddad
但是我怎么知道哪一行正在更新?说我想知道该行的主键,怎么做?在添加新项目之后发送电子邮件的事情,但是电子邮件收件人将根据第二个表中的值来决定,其中外键ID位于第一个表中(具有触发器的表) - johnshaddad
mrdenny对Joel Coehoorn回答的评论是一个很好的总结。