SQL Server:INSTEAD OF触发器会影响参照完整性检查吗?

时间:2011-06-29 20:29:40

标签: sql sql-server sql-server-2005 tsql triggers

如果引用的内容不存在,我想将外键设置为null。但是,我希望所有其他参照完整性检查正常工作。

INSTEAD OF触发器会强制我写出所有完整性检查吗?

由于触发器无法更改插入的表,并且由于参照完整性而无法在目标表中存在数据,是否有办法将这些外键置空以便记录可以保存?

编辑:我犯的最大错误是,如果存在INSTEAD OF触发器,则不知道数据库不会进行任何更改。触发器必须对表本身进行更改。

2 个答案:

答案 0 :(得分:1)

如果外键可以为空,则可以使用ON DELETE SET NULL,如果删除引用的行,则会将外键更新为NULL。

ON DELETE SET DEFAULT是另一种可能性,具体取决于您的申请。

答案 1 :(得分:1)

正如@Catcall指出的那样,ON DELETE SET NULL引用操作可以满足您的需求。

那就是说,是的,您可以编写一个INSTEAD OF触发器来执行相同的操作(或主题的变体),而无需自己处理所有参照完整性约束。这是一个简短的例子:

表格和测试数据:

CREATE TABLE T1 (ID INTEGER NOT NULL UNIQUE);
CREATE TABLE T2 (ID INTEGER REFERENCES T1 (ID));

INSERT INTO T1 VALUES (1), (2), (3);
INSERT INTO T2 VALUES (1), (2), (3), (2), (3), (3);

触发器:

-- 'CREATE TRIGGER' must be the first statement in a batch.
CREATE TRIGGER tr__T1__instead_of_delete
ON T1
INSTEAD OF DELETE
AS
BEGIN;

UPDATE T2
   SET ID = NULL
 WHERE EXISTS (
               SELECT * 
                  FROM deleted
                 WHERE deleted.ID = T2.ID
              );

DELETE
  FROM T1
 WHERE EXISTS (
               SELECT * 
                  FROM deleted
                 WHERE deleted.ID = T1.ID
              );

END;

测试触发器:

DELETE 
  FROM T1 
 WHERE ID = 3;