繁体   English   中英

MS SQL中的自引用约束

[英]Self-referencing constraint in MS SQL

MS SQL是否使用ON DELETE CASCADE选项限制自引用约束? 我有一个父子关系表,PARENT_ID列是ID的外键。 使用ON DELETE CASCADE选项创建它会导致错误

“引入FOREIGN KEY约束可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。”

我无法相信我必须在递归模式下删除此层次结构。 除了触发器有什么问题吗?

在这种情况下,您无法在具有自引用约束的表上设置ON DELETE CASCADE。 存在潜在的周期性逻辑问题,因此它不会允许它。

有一个很好的文章在这里 -尽管它是8,而不是SQL版本9 -尽管适用同样的规则。

我刚刚回答了另一个问题这个问题被重复了。 我认为值得在这里提出我的答案:

这是不可能的。 你可以通过INSTEAD OF TRIGGER来解决这个问题

create table locations 
(
    id int identity(1, 1),
    name varchar(255) not null,
    parent_id int,

    constraint pk__locations
        primary key clustered (id)

)
GO

INSERT INTO locations(name,parent_id)  VALUES
 ('world',null)
,('Europe',1)
,('Asia',1)
,('France',2)
,('Paris',4)
,('Lyon',4);
GO

- 此触发器将使用递归CTE来获取您要删除的所有ID之后的所有ID。 这些ID将被删除。

CREATE TRIGGER dbo.DeleteCascadeLocations ON locations
INSTEAD OF DELETE 
AS
BEGIN
    WITH recCTE AS
    (
        SELECT id,parent_id
        FROM deleted

        UNION ALL

        SELECT nxt.id,nxt.parent_id
        FROM recCTE AS prv
        INNER JOIN locations AS nxt ON nxt.parent_id=prv.id
    )
    DELETE FROM locations WHERE id IN(SELECT id FROM recCTE);
END
GO

- 在这里测试,尝试使用不同的ID。 您可以尝试WHERE id IN(4,3) ...

SELECT * FROM locations;

DELETE FROM locations WHERE id=4;

SELECT * FROM locations
GO

- 清理(仔细查看真实数据!)

if exists(select 1 from INFORMATION_SCHEMA.TABLES where TABLE_NAME='locations')
---DROP TABLE locations; 
CREATE TRIGGER MyTable_OnDelete ON MyTable
INSTEAD OF DELETE
AS 
BEGIN

  SET NOCOUNT ON;

  DELETE FROM mt
  FROM   deleted AS D
  JOIN   MyTable AS mt
  ON     d.Id = mt.ParentId

  DELETE FROM mt
  FROM   deleted AS D
  JOIN   MyTable AS mt
  ON     d.Id = mt.Id

END

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM