SQL Server我的级联循环在哪里?

时间:2016-01-30 00:57:05

标签: sql-server constraints

在我的数据库中,有两个表:[Node][NodeDetail]

[节点]:

CREATE TABLE [dbo].[Node] 
(
    [ID]                   UNIQUEIDENTIFIER DEFAULT (newid()) NOT NULL,
    [Name]                 NVARCHAR (100)   NOT NULL,
    [Description]          NVARCHAR (MAX)  NULL,
    [NodeTypeID]           UNIQUEIDENTIFIER NOT NULL,

    CONSTRAINT [pk_Node] PRIMARY KEY NONCLUSTERED ([ID]),

    CONSTRAINT [fk_Node_NodeTypeID] 
        FOREIGN KEY ([NodeTypeID]) REFERENCES [dbo].[NodeType] ([ID]) 
            ON DELETE NO ACTION ON UPDATE CASCADE,
    CONSTRAINT [pk_NodeName] UNIQUE CLUSTERED ([Name] ASC, [NodeTypeID] ASC)
);

CREATE NONCLUSTERED INDEX [ix_Node_NodeTypeID]
ON [dbo].[NodeType]([NodeTypeID] ASC);

[NodeDetail]:

CREATE TABLE [dbo].[NodeDetail] 
(
    [ID]                   UNIQUEIDENTIFIER DEFAULT (newid()) NOT NULL,
    [ParentNodeID]         UNIQUEIDENTIFIER NOT NULL,
    [ChildNodeID]          UNIQUEIDENTIFIER NULL,
    [UnimportantProperty]  INT              NULL,
    [ImportantProperty]    DECIMAL (19, 6)  DEFAULT ((0)) NOT NULL,
    …

    CONSTRAINT [pk_NodeDetail] PRIMARY KEY CLUSTERED ([ID] ASC),
    CONSTRAINT [fk_NodeDetail_ChildNodeID] 
        FOREIGN KEY ([ChildNodeID]) REFERENCES [dbo].[Node] ([ID]) 
             ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT [fk_NodeDetail_ParentNodeID] 
        FOREIGN KEY ([ParentNodeID]) REFERENCES [dbo].[Node] ([ID]) 
             ON DELETE CASCADE ON UPDATE CASCADE
);

CREATE NONCLUSTERED INDEX [ix_NodeDetail_ParentNodeID]
ON [dbo].[NodeDetail]([ParentNodeID] ASC);


CREATE NONCLUSTERED INDEX [ix_NodeDetail_ChildNodeID]
ON [dbo].[NodeDetail]([ChildNodeID] ASC);

当我尝试部署到Azure中的真实数据库时,它开始抱怨fk_NodeDetail_ChildNodeID

  

可能导致循环或多个级联路径

现在,我正试图看看这些周期可能发生的地方以及如何打破它们,但我无法识别。

据我了解,删除[dbo].[Node] where [ID] = 1后,[dbo].[NodeDetail] where [ChildNodeID] = 1中的所有条目都将被删除。同时,[dbo].[NodeDetail] where [ParentNodeID] = 1中的所有条目也将被删除。

[dbo].[NodeDetail]中的任何属性都不是任何其他表中的外键,因此我不明白它可以传播到何处。

整个事物展开成一棵树。目标是确保每当删除节点或更改其ID(可能发生)时,将相应地删除或更新将其连接到另一个节点的节点详细信息。 NodeDetail上有一个ID,因为在两个不同的节点之间可能存在多个具有不同属性的NodeDetail

编辑:

所以我找到了原因,即两个FK在同一个表中引用相同的列。在SQL Server的思想中,当两者都指向同一条目时,更改该条目可能需要更改两个FK。通过一些不可思议的逻辑,这意味着一个循环或多个级联路径。

坏消息:这不是由CHECK约束修复的(如果你的版本支持它)。要将树折叠到数据库中,必须使用过程和触发器来消除垃圾。

0 个答案:

没有答案