2013-03-23 103 views
2

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

谢谢。

回答

3

你可以做

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 

或拒绝对这些列的UPDATE权限。

这两种方法都会拒绝任何更新PK列的尝试,而不管这些值是否实际改变。 SQL Server没有行级触发器,除非表中有一列(保证不可变),否则在触发器中没有可靠的方法来告知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 
+0

非常感谢你! – Cosmin 2013-03-23 11:44:42

相关问题