首页 > 解决方案 > 将旧值插入审计表的 SQL 更新触发器,仅在更新两个特定列时触发,否则返回错误

问题描述

当客户表中更新时,我需要记录所有以前的地址和邮政编码。

业务要求:如果不更新邮政编码,则无法更改地址,反之亦然。

需要一种防止这种情况的机制以及适当的错误消息。

我已经创建了表:

create table tblCustomerAudit
(
CustomerID int identity(1,1) not null,
CustomerName nvarchar(255) null,
CustomerAddress nvarchar(255) null,
CustomerPostcode nvarchar(255) null,
CardNumber nvarchar(255) null,
)
go

alter table tblCustomerAudit
add constraint FK_CustomerAudit
foreign key(CustomerID)
references CstmrEng.tblCustomer(CustomerID)

触发器会是什么样子?请帮忙!

标签: sqlsql-servertriggerssql-server-2016

解决方案


我真的推荐一个存储过程来控制更新、插入和删除,因此您将使用存储过程在值进入表之前传递值。如果您使用触发器,那么值将实际更改,然后触发器将被触发,并且如果您的条件满足,您必须从触发器中使用旧值重新更新表。所以,这对我来说是一种冗余,这就是为什么我建议在更改表值之前使用存储过程来处理所有事情。

无论如何,您仍然可以使用具有删除和插入表优势的触发器:

CREATE TRIGGER CustomerUpdate ON   tblCustomerAudit
   FOR UPDATE
AS 
BEGIN
    SET NOCOUNT ON;
  DECLARE 
        @CustomerID             INT
    ,   @New_CustomerAddress    nvarchar(255)
    ,   @New_CustomerPostcode   nvarchar(255)
    ,   @Old_CustomerAddress    nvarchar(255)
    ,   @Old_CustomerPostcode   nvarchar(255)

    SELECT 
        @CustomerID             = CustomerID 
    ,   @Old_CustomerAddress    = CustomerAddress
    ,   @Old_CustomerPostcode   = CustomerPostcode
    FROM 
        deleted

    SELECT 
        @New_CustomerAddress    =   CustomerAddress
    ,   @New_CustomerPostcode   =   CustomerPostcode
    FROM
        tblCustomerAudit 
    WHERE 
        CustomerID = @CustomerID


    IF @Old_CustomerAddress = @New_CustomerAddress OR @New_CustomerPostcode = @Old_CustomerPostcode 
    BEGIN 
        -- IF one of them matches return the old values
        UPDATE tblCustomerAudit
        SET 
            CustomerAddress  = @Old_CustomerAddress
        ,   CustomerPostcode = @Old_CustomerPostcode
        WHERE 
            CustomerID = @CustomerID

        -- display an error message 
        RAISERROR( 'You need to change both address and postcode to save the new values', 18 , 0);

    END






END

推荐阅读