我认为这是一个非常简单的要求,但因为我是新手,我无法让它正常工作。
我有一个表格,其中包含pk为cust_no
的客户数据。当插入新的客户行,并且电子邮件地址字段不为空时,我想在同一行中将日期字段设置为getdate()
。
如果使用新的电子邮件地址更新客户记录,我也想做同样的事情,但同样,只有当电子邮件地址字段不为空,并且实际上使用新的电子邮件地址更新时。
这样做的目的是运行在特定时间范围内收集的新电子邮件地址的报告。
非常感谢任何帮助。谢谢!
答案 0 :(得分:2)
需要记住的一点是,很多人都会出错:SQL Server中的触发器每个语句称为一次 - 每行不会一次。
因此,如果您碰巧有一个INSERT
或UPDATE
语句一次插入或更新50行 - 您的触发器将被称为一次,以及伪表( UPDATE案例中的Inserted
和Deleted
将包含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的那些行,并且在更新之后现在不更新。所以你需要加入Deleted
伪表,其中包含“旧”值(在UPDATE之前)。
所有已更新的行,Deleted
中电子邮件的旧值为NULL,且Customer表中的当前值为NOT NULL - 这些是您要更新的行。的日期列。
-- 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