1

我有一个我认为非常简单的要求,但是因为我是新手,所以我不能让它正常工作。

我有一个充满客户数据的表,其 pk 为cust_no. 当插入新客户行并且电子邮件地址字段不为空时,我想将同一行中的日期字段设置为getdate().

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

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

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

4

1 回答 1

2

需要记住的重要一点是很多人都犯了错误:SQL Server 中的触发器在每条语句中调用一次,而不是每行调用一次。

因此,如果您碰巧有一个INSERTorUPDATE语句一次插入或更新 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伪表(包含刚刚插入的所有行 - 及其所有列值)与“真实”客户表相结合,然后更新刚刚插入的所有客户行,以及电子邮件列不在的位置空值。

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

所有那些已更新的行,其中电子邮件的旧值为DeletedNULL,而 Customer 表中的当前值不是 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  
于 2013-02-22T17:18:46.160 回答