同一张表上的两个外键:如何在删除级联上实现?

时间:2019-05-14 14:51:02

标签: sql-server foreign-keys ddl

我有一个有两列的表。它们每个都是指向同一第二张表的外键:

CREATE TABLE [dbo].[TBL_TOGETHER]
(
    [ID1] [int] NULL FOREIGN KEY REFERENCES [TBL_ANOTHER_TABLE](ID),
    [ID2] [int] NULL FOREIGN KEY REFERENCES [TBL_ANOTHER_TABLE](ID)
)

但是现在我无法再从TBL_ANOTHER_TABLE中删除实体:

  

DELETE语句与REFERENCE约束“ FK__TBL_ASD__4DE98D56”相冲突。

我的问题是:在ON DELETE CASCADE实施TBL_TOGETHER的最佳解决方案是什么?

我试图在外键上添加ON DELETE SET NULLON DELETE CASCADE,但是由于循环或多个级联路径,它不起作用。

我尝试在TBL_ANOTEHR_TABLE上添加删除触发器,但它仍与外键冲突:

ALTER TRIGGER REMOVE_FORENGKEY
ON TBL_ANOTHER_TABLE 
FOR DELETE
AS
BEGIN
    UPDATE TBL_TOGETHER
    SET TBL_TOGETHER.ID1 = NULL
    FROM TBL_TOGETHER
    JOIN deleted ON TBL_TOGETHER.ID1 = deleted.ID;

    UPDATE TBL_TOGETHER
    SET TBL_TOGETHER.ID2 = NULL
    FROM TBL_TOGETHER
    JOIN deleted ON TBL_TOGETHER.ID2 = deleted.ID;
END

我尝试了INSTEAD OF DELETE触发,但是这种方法也不起作用,因为被引用的表ALSO包含具有级联约束的外键。

ALTER TRIGGER REMOVE_FORENGKEY
ON TBL_ANOTHER_TABLE 
INSTEAD OF DELETE
AS
BEGIN
    UPDATE TBL_TOGETHER
    SET TBL_TOGETHER.ID1 = NULL
    FROM TBL_TOGETHER
    JOIN deleted ON TBL_TOGETHER.ID1 = deleted.ID;

    UPDATE TBL_TOGETHER
    SET TBL_TOGETHER.ID2 = NULL
    FROM TBL_TOGETHER
    JOIN deleted ON TBL_TOGETHER.ID2 = deleted.ID;

    DELETE TBL_ANOTHER_TABLE 
    FROM TBL_ANOTHER_TABLE 
    JOIN deleted ON TBL_ANOTHER_TABLE.ID = deleted.ID 
    WHERE TBL_ANOTHER_TABLE.ID = deleted.ID;
END

错误:

  

无法更改表'TBL_ANOTHER_TABLE'上的INSTEAD OF DELETE或INSTEAD OF UPDATE触发器'REMOVE_FORENGKEY'。这是因为表具有带有级联DELETE或UPDATE的FOREIGN KEY。

1 个答案:

答案 0 :(得分:0)

使用此触发器: 此触发器起作用而不是删除。因此,在将引用设置为null后,您必须删除记录。

 CREATE TRIGGER Trigger_TBL_ANOTHER_TABLE
    ON [dbo].[TBL_ANOTHER_TABLE]
    INSTEAD OF DELETE
    AS 
    BEGIN

        SET NOCOUNT ON;

        UPDATE  t
        SET     t.ID1 = NULL
        from [dbo].[TBL_TOGETHER] t inner join
        deleted d on d.ID = t.ID1

        UPDATE  t
        SET     t.ID2 = NULL
        from [dbo].[TBL_TOGETHER] t inner join
        deleted d on d.ID = t.ID2

        DELETE  t
        from [dbo].[TBL_ANOTHER_TABLE] t inner join
        deleted d on d.ID = t.ID

    END
    GO