如何构建触发器以在更新时记录先前的值?

时间:2017-03-14 20:54:05

标签: sql sql-server sql-server-2012

编辑:我正在使用SQL Server 2012

我正在处理一个项目,其中表中的两列需要在更新时记录其数据。因此,为了使其工作,当某人决定更新地址或邮政编码并保存时,审计表需要记录 列之前的 列中的先前值更新。

我已经开始设置一个审核表来保存所需的数据

CREATE TABLE Customer_Audit
(
Cust_UpdateID int IDENTITY (1,1),
Cust_User char (8),
Cust_Update_Date date,
Cust_ID int, 
CustomerAddresss nvarchar (255),
CustomerZipCode nvarchar (255),

CONSTRAINT [pk_Cust_UpdateID] PRIMARY KEY (Cust_UpdateID)

)

我面临的唯一问题是建立一个实际的触发器查询,用来自customer表的所需数据填充审计表。我被告知AFTER UPDATE触发器是理想的,但我不知道如何正确设置它并获取我需要的数据并填充审计表本身。

有人可以推荐并告诉我如何设置一个触发器,可以做我想做的事情吗?

2 个答案:

答案 0 :(得分:2)

您可以使用"已删除"和"插入"触发器中的表:https://msdn.microsoft.com/en-us/library/ms191300(v=sql.110).aspx

CREATE TRIGGER Customer_update_trig ON Customer
AFTER UPDATE
AS
BEGIN
  INSERT INTO Customer_Audit (Cust_User, Cust_Update_Date, Cust_ID, CustomerAddresss, CustomerZipCode)
  SELECT d.Cust_User,
    d.Cust_Update_Date,
    d.Cust_ID,
    d.CustomerAddresss, --sic
    d.CustomerZipCode
  FROM deleted d
END

-- OR for auto generated user and timestamp

CREATE TRIGGER Customer_update_trig ON Customer
AFTER UPDATE
AS
BEGIN
  INSERT INTO Customer_Audit (Cust_User, Cust_Update_Date, Cust_ID, CustomerAddresss, CustomerZipCode)
  SELECT CURRENT_USER,
    GETDATE(),
    d.Cust_ID,
    d.CustomerAddresss, --sic
    d.CustomerZipCode
  FROM deleted d
END

当然,您也希望将您的架构名称放在那里(或者如果使用默认设置,则为' dbo')。并仔细检查它们与原始表匹配的列名称。

对于您的审核策略,您需要决定是否只想在更新后进行记录,还是急切地记录原始插入内容。

审核表中进行SELECT优化的另一个方面是,如果您有WHERECust_Record_Start_Time可以为时间提供范围,则可以提高效率Cust_Record_End_Time条款记录有效。使用该数据查询某个时间点要容易得多。

我不再拥有SQL Server,所以我无法测试语法,但概念应该存在。

此外,如果添加此触发器会给UPDATE语句增加太多时间,您可以查看Service Broker:https://msdn.microsoft.com/en-us/library/bb522893(v=sql.110).aspx

它允许异步保证"消息"这可以在非常接近实时的情况下更新您的审计表。

答案 1 :(得分:0)

您可以在触发器中引用旧值和新值,允许您引用所需数据并将其导入审计表。从您的描述中不清楚从Customer表中确切地获取了哪些数据,所以我假设所有审计字段在Customer表中都具有等效字段,但Cust_UpdateID除外

CREATE TRIGGER update_audit_table
    AFTER UPDATE
    ON Customer
    BEGIN
      INSERT INTO Customer_Audit(Cust_User, Cust_ID, Cust_Update_Date, CustomerAddress, CustomerZipCode)
      VALUES (OLD.Cust_User, OLD.Cust_ID, OLD.Cust_Update_date, OLD.CustomerAddress, OLD.CustomerZipCode)
    END

注意:在触发器中,OLD是对更改之前的行的引用,而NEW将是对更改后的行的引用。