如何使用触发器更新SQL Server中的列

时间:2019-04-01 16:32:02

标签: sql-server tsql triggers

我正在尝试在SQL Server Management Studio中创建一个触发器,当在同一表中更新了单独的列时,该列的值将增加1。

运行更新脚本后我们要更新的列的值变为NULL

我的例子是当我更改客户地址时,我希望每次地址更改时列都增加1,即NoOfAddressess = 1、2、3等...

这是我正在编写的SQL代码

ALTER TRIGGER trg_customeraudit 
ON tblCustomer
AFTER UPDATE, DELETE, INSERT
AS
    INSERT INTO dbo.CustomerDetailsAudit 
    VALUES (CURRENT_USER, CURRENT_TIMESTAMP, 
            (SELECT CustomerID FROM inserted), 
            (SELECT CustomerAddress FROM deleted), 
            (SELECT CustomerAddress FROM inserted),
            (SELECT CustomerPostcode FROM deleted), 
            (SELECT CustomerPostcode FROM inserted), 
            (SELECT NumberOfChangedAddresses FROM dbo.CustomerDetailsAudit)  
           )

    IF ((SELECT CustomerAddress FROM inserted) = 
        (SELECT CustomerAddress FROM deleted) OR 
        (SELECT CustomerPostcode FROM deleted) = 
        (SELECT CustomerPostcode FROM inserted))
    BEGIN
        RAISERROR ('You must enter both a new postcode and address',16,10)
        ROLLBACK TRANSACTION
    END 
ELSE
BEGIN 
    PRINT 'Transaction successful'
    WHERE CustomerID = (SELECT CustomerID from inserted)
END

IF UPDATE (CustomerName)
BEGIN
    RAISERROR ('You cannot change the customer name', 16, 10)
    ROLLBACK
END

1 个答案:

答案 0 :(得分:0)

依赖于此数据触发器上发生的其他事情,可能是一种非常低效的处理方法,但这是一种可能的解决方案。

1。设置

首先创建一个表用于测试。

create table test_table (
      MyPrimaryKey int primary key clustered not null identity(1, 1)
    , SomeColumn varchar(255) not null
    , SomeColumnCounter int null
);
go

现在,添加一个触发器以将计数器初始化为1。这可以通过默认约束进行处理,也可以在应用程序级别进行设置,但是也可以使用触发器来完成。

-- this trigger will set the counter to 1 when a record is first added
-- doesn't need to be a trigger, but since the question was on triggers
create trigger trg_test_table_insert
    on test_table
    after insert
as
    update tt
        set tt.SomeColumnCounter = 1
    from
        test_table as tt
    inner join
        Inserted as i
        on
            tt.MyPrimaryKey = i.MyPrimaryKey;
go

现在,添加一个触发器,该触发器将检查指定列上的更改并在需要时增加计数器。

-- this trigger will increment the counter by 1 if 'SomeColumn' changed
-- doesn't handle nulls so will need to be modified depending on schema
create trigger trg_test_table_update
    on test_table
    after update
as
    update tt
        set tt.SomeColumnCounter = tt.SomeColumnCounter + 1
    from
        Inserted as i -- new version of the record
    inner join
        Deleted as d -- old version of the record
        on
            i.MyPrimaryKey = d.MyPrimaryKey
            and i.SomeColumn <> d.SomeColumn
    inner join
        test_table as tt
        on
            tt.MyPrimaryKey = i.MyPrimaryKey
go

2。测试

添加一些测试数据。

insert into test_table (SomeColumn)
values ('abc'), ('def');
go

现在我们有:

MyPrimaryKey    SomeColumn  SomeColumnCounter
1               abc         1
2               def         1

无需更改即可进行更新:

update tt
    set tt.SomeColumn = 'abc'
from
    test_table as tt
where
    tt.MyPrimaryKey = 1

我们还有:

MyPrimaryKey    SomeColumn  SomeColumnCounter
1               abc         1
2               def         1

实际上会更改某些内容的更新:

update tt
    set tt.SomeColumn = 'abbc'
from
    test_table as tt
where
    tt.MyPrimaryKey = 1

现在我们有:

MyPrimaryKey    SomeColumn  SomeColumnCounter
1               abbc        2
2               def         1

将更改所有内容的更新:

update tt
    set tt.SomeColumn = tt.SomeColumn + 'z'
from
    test_table as tt

现在我们有:

MyPrimaryKey    SomeColumn  SomeColumnCounter
1               abbcz       3
2               defz        2