如果外键引用的内容不存在,我想将其设置为null。但是,我希望所有其他引用完整性检查都能正常工作。
INSTEAD OF
触发器会强制我编写所有完整性检查吗?
由于触发器不能更改插入的表,并且由于引用完整性,数据不能存在于目标表中,是否有方法将这些外键置空以便保存记录?
编辑:我犯的最大错误是不知道如果存在INSTEAD OF
触发器,数据库不会进行任何更改。触发器必须对表本身进行更改。
如果外键可以为NULL,则可以使用ON DELETE SET NULL
,如果删除了引用的行,则会将外键更新为NULL。
ON DELETE SET DEFAULT
是另一种可能性,具体取决于您的应用程序。
正如@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;