创建不允许更新主键列的触发器



我有一个表,它有一个由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中查看这些值是否发生了变化。我的问题是,我可以不使用光标来检查这个吗?

谢谢。

你可以做

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是否实际上被更新了。

例如,下面表上的UPDATE触发器中的INSERTEDDELETED表对于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

最新更新