如果引用的内容不存在,我想将外键设置为null。但是,我希望所有其他参照完整性检查正常工作。
INSTEAD OF
触发器会强制我写出所有完整性检查吗?
由于触发器无法更改插入的表,并且由于参照完整性而无法在目标表中存在数据,是否有办法将这些外键置空以便记录可以保存?
编辑:我犯的最大错误是,如果存在INSTEAD OF
触发器,则不知道数据库不会进行任何更改。触发器必须对表本身进行更改。
答案 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;