需要注意的一点是很多人会出错:SQL Server中的触发器被称为每个语句一次 - 不是每行一次。您的触发器将被称为一次,以及(在UPDATE情况下Inserted
和Deleted
)伪表将包含50行 - 如果你碰巧有一个INSERT
或UPDATE
语句插入或更新一次50行
所以。编写触发器时需要考虑到这一点。
的INSERT情况比较简单 - 所以这里有云:
-- CREATE after INSERT trigger
CREATE TRIGGER trgCustomerInsert
ON dbo.Customer AFTER INSERT
AS
-- update your "Customer" table
UPDATE dbo.Customer
SET SomeDateColumn = GETDATE() -- set date column to GETDATE()
FROM dbo.Customer c
INNER JOIN Inserted i ON c.cust_no = i.cust_no -- on all those rows inserted
WHERE c.Email IS NOT NULL -- where the e-mail address is NOT NULL
你基本上只是加入Inserted
伪表(包含所有行刚刚插入 - 他们所有的列值)对“真实”客户表,并更新所有刚刚插入的客户行,以及电子邮件列的NOT NULL。
更新是有点棘手 - 因为你只想更新那些电子邮件柱NULL前行,现在是NOT NULL,更新后。因此,您需要加入Deleted
伪表,其中包含“旧”值(在UPDATE之前)。
所有已更新的行以及Deleted
中的电子邮件的旧值为NULL且Customer表中的当前值不为空 - 那些是您要更新日期列的那些行对于。
-- CREATE after UPDATE trigger
CREATE TRIGGER trgCustomerUpdate
ON dbo.Customer AFTER UPDATE
AS
-- update your "Customer" table
UPDATE dbo.Customer
SET SomeDateColumn = GETDATE() -- set date column to GETDATE()
FROM dbo.Customer c
INNER JOIN Deleted d ON c.cust_no = d.cust_no
WHERE
-- where new value of e-mail is NOT NULL
-- and the old value (in "Deleted") was in fact NULL
c.Email IS NOT NULL AND d.EMail IS NULL
非常感谢您,我从您的回复中了解到很多。我正在实施它,会让你知道它是如何发展的。感谢您指出整个批次已更新的事实,而不仅仅是一行。这是我在这个狭隘的方法中忽略的东西。 – user2100137 2013-03-01 20:32:43
@ user2100137:很高兴能有所帮助! – 2013-03-01 22:07:03