SQL Server 2008 - 使用约束添加自引用外键并获取“无法找到数据类型”错误

时间:2014-07-18 20:48:21

标签: sql sql-server

我正在使用SQL Server 2008,并尝试使用ON DELETE CASCADE约束添加自引用外键,但遇到了一些问题。基本上我希望系统在删除节点时自动删除层次结构中所有节点的子节点。

我有一个表 Node ,其基本结构如下:

  • PK_Node_Id(主键)
  • ParentNodeId(想要使用ON DELETE CASCADE约束使其成为自引用外键。

问题出在我尝试添加约束时。如果我使用GUI Designer, INSERT和UPDATE规范选项将显示为灰色,我无法执行任何操作。

如果我尝试运行SQL语句来添加约束:

ALTER TABLE Node
ADD CONSTRAINT
FK_Node_Node
FOREIGN KEY (ParentNodeId)
REFERENCES Node (PK_Node_Id)
ON DELETE CASCADE;

我收到以下错误:

Cannot find data type FK_Node_Node.

FK_Node_Node 是我的外键名称。不确定为什么要求或寻找数据类型......

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

  

我收到以下错误:找不到数据类型FK_Node_Node。

我怀疑你拼错了#34; CONSTRAINT"当您运行ALTER TABLE语句时。结果语句在语法上仍然有效,但它不是添加外键约束,而是添加一个名为(例如)" CONSTAINT"的#em>列。类型为FK_Node_Node,加上未命名的外键约束。

  

我希望系统在删除节点时自动删除层次结构中所有节点的子节点。

不幸的是,这是不可能的:SQL Server不允许级联引用操作来形成周期。 ALTER TABLE语句应该给出的错误是:

  

介绍FOREIGN KEY约束' FK_Node_Node'在表格'节点'可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。

您需要自己执行递归删除,而不是使用ON DELETE CASCADE:

;WITH Nodes (PK_Node_Id) AS
(
    SELECT PK_Node_Id
    FROM Node
    WHERE PK_Node_Id = @NodeId  -- @NodeId is the root node you want to delete

    UNION ALL

    SELECT Child.PK_Node_Id
    FROM Node Child JOIN Nodes Parent ON Parent.PK_Node_Id = Child.ParentNodeId
)
DELETE FROM Node
WHERE PK_Node_Id IN (SELECT PK_Node_Id FROM Nodes)