3

我有一个表,它有一个由 3 列组成的复合主键,比如说 A、B、C。我想创建一个触发器,它UPDATE会检查这三列是否不会更改。这是我到目前为止所拥有的,但它似乎不起作用:

CREATE TRIGGER TableTrigger
ON Table
AFTER INSERT, UPDATE AS
BEGIN
    IF (EXISTS (SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted))
    BEGIN
    -- Update Operation
    IF (SELECT COUNT(*) FROM inserted WHERE A IS NOT NULL OR B IS NOT NULL OR C IS NOT NULL) > 0
    BEGIN
        RAISERROR('Error, you cannot change Primary Key columns', 16, 1)
        ROLLBACK
        RETURN
    END
END

我期待如果我更新表中inserted的某些值,我不会更新为 NULL 的列的值,但事实并非如此。我在某个地方读到了我需要查看inserteddeleted查看这些值是否更改的地方。所以我的问题是,我可以在不使用光标的情况下检查吗?

谢谢你。

4

1 回答 1

4

你可以做

CREATE TRIGGER TableTrigger
ON Table
AFTER UPDATE AS
BEGIN
IF UPDATE(A) OR UPDATE(B) OR UPDATE(C) 
    BEGIN
        RAISERROR('Error, you cannot change Primary Key columns', 16, 1)
        ROLLBACK
        RETURN
    END
END

或者拒绝这些列的更新权限。

无论值是否实际更改,这两种方法都会拒绝任何更新 PK 列的尝试。SQL Server 没有行级触发器,除非IDENTITY表中有列(保证不可变),否则没有可靠的方法可以在触发器中判断 PK 是否实际更新。

例如INSERTED,下DELETED表的UPDATE触发器中的和表对于这两个UPDATE语句都是相同的。

CREATE TABLE T(C INT PRIMARY KEY);

INSERT INTO T VALUES (1),(-1)

/*Both values swapped*/
UPDATE T SET C = -C

/*Both values left the same*/
UPDATE T SET C = C
于 2013-03-23T11:30:49.550 回答