Sql server 基于字段值的插入和/或更新记录的SQL Server触发器

Sql server 基于字段值的插入和/或更新记录的SQL Server触发器,sql-server,tsql,triggers,Sql Server,Tsql,Triggers,我有一个我认为很简单的要求,但因为我是新来的,我不能让它正常工作 我有一个满表的客户数据,主键为cust\u no。当插入新的客户行,并且电子邮件地址字段不为空时,我希望将同一行中的日期字段设置为getdate() 如果客户记录被更新为新的电子邮件地址,我也会做同样的事情,但同样,只有当电子邮件地址字段不为空,并且实际被更新为新的电子邮件地址时 其目的是运行在特定时间范围内收集的新电子邮件地址的报告 任何帮助都将不胜感激。谢谢大家! 需要记住的一点是,很多人都会出错:SQL Server中的触发

我有一个我认为很简单的要求,但因为我是新来的,我不能让它正常工作

我有一个满表的客户数据,主键为
cust\u no
。当插入新的客户行,并且电子邮件地址字段不为空时,我希望将同一行中的日期字段设置为
getdate()

如果客户记录被更新为新的电子邮件地址,我也会做同样的事情,但同样,只有当电子邮件地址字段不为空,并且实际被更新为新的电子邮件地址时

其目的是运行在特定时间范围内收集的新电子邮件地址的报告


任何帮助都将不胜感激。谢谢大家!

需要记住的一点是,很多人都会出错:SQL Server中的触发器在每个语句中调用一次,而不是每行调用一次

因此,如果您碰巧有一个
INSERT
UPDATE
语句,该语句一次插入或更新50行,那么触发器将一次调用,并且伪表(
Inserted
Deleted
在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
伪表(包含所有刚插入的行及其列值)与“real”customer表连接起来,然后更新所有刚插入的客户行,其中电子邮件列不为NULL

更新有点棘手,因为您只想更新那些电子邮件列在更新之前为NULL,而在更新之后现在不为NULL的行。因此,您需要加入
Deleted
伪表,该表包含“旧”值(在更新之前)

已更新的所有行,以及
已删除的
中电子邮件的旧值为NULL,并且客户表中的当前值不为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  

非常感谢,我从你的回复中学到了很多。我现在正在实施,我会让你知道进展如何。感谢您指出这样一个事实,即整个批次都在更新,而不仅仅是一行。这是我在处理这件事时所忽略的。@user2100137:很高兴能帮上忙!