我有一个表,它有一个由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,但事实并非如此。我在某个地方读到,我需要在inserted
和deleted
中查看这些值是否发生了变化。我的问题是,我可以不使用光标来检查这个吗?
谢谢。
你可以做
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
触发器中的INSERTED
和DELETED
表对于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