【问题标题】:Violation of PRIMARY KEY constraint 'PK_OrgNode'. Cannot insert duplicate key in object 'dbo.#Org'. The duplicate key value is (0x)违反主键约束“PK_OrgNode”。无法在对象“dbo.#Org”中插入重复键。重复键值为 (0x)
【发布时间】:2019-05-16 13:01:17
【问题描述】:

sql server 中的层次结构数据类型有重复

我有下表

ChildID ParentID
1   0
1   2
4   3
1   4
2   6
4   8

作为父子关系的基础

运行查询:

CREATE TABLE #Org (
OrgNode [hierarchyid],  
ChildID int,
ParentID int  
CONSTRAINT PK_OrgNode PRIMARY KEY CLUSTERED (OrgNode));  

CREATE TABLE #Child (
ChildID int, 
ParentID int,
Num int);  
CREATE CLUSTERED INDEX tmpind ON #Child(ParentID, ChildID); 

INSERT INTO #Child 
SELECT  DISTINCT
ChildID = ChildID,
ParentID = ParentID, 
Num = ROW_NUMBER() OVER (PARTITION BY ParentID ORDER BY ParentID)
FROM #tmpEntity;

结果如预期:

ChildID ParentID    Num
1   0   1
1   2   1
4   3   1
1   4   1
2   6   1
4   8   1

运行下一步时

WITH paths(path, ChildID)   
AS 
(SELECT hierarchyid::GetRoot() AS OrgNode, ChildID   
 FROM #Child AS C   
 WHERE ParentID = 0   
 UNION ALL
 SELECT CAST(p.path.ToString() + CAST(C.Num AS varchar(30)) + '/' AS hierarchyid), C.ChildID  
 FROM #Child AS C   
 JOIN paths AS p ON C.ParentID = P.ChildID)  
INSERT #Org (OrgNode, O.ChildID, O.ParentID)  
SELECT P.path, O.ChildID, O.ParentID  
FROM #tmpEntity AS O   
JOIN Paths AS P ON O.ChildID = P.ChildID
OPTION (maxrecursion 0)
GO 

现在会报错

“消息 2627,级别 14,状态 1,第 170 行违反主键 约束“PK_OrgNode”。无法在对象中插入重复键 'dbo.#Org'。重复键值为 (0x)。该声明已 终止。”

任何人都可以帮助或查看错误在哪里吗? 谢谢

【问题讨论】:

  • 您好,欢迎来到 SO。尝试发布 ddl 和示例数据的工作做得很好。但是,表名不匹配,并且没有#Org 的数据。如果该数据是样本数据的第一位,则缺少hierarchyid。不要害怕在代码中使用制表符和空格,以便您阅读。
  • +1 @SeanLange 的反馈。这对我来说可能是一个学习机会,但hierarchyid::GetRoot() 是什么?
  • @Brian 它是 hierarchyid 数据类型的方法之一。 docs.microsoft.com/en-us/sql/t-sql/data-types/…
  • @user9416131,如果注释掉INSERT #Org (OrgNode, O.ChildID, O.ParentID)这一行,只看select的结果,结果如何?
  • @Sean Lange,数据是通过脚本的早期部分填充的。 #Org 的数据是通过 with 语句中的脚本填充的。

标签: sql-server


【解决方案1】:

消息:

“消息 2627,级别 14,状态 1,第 170 行违反主键约束“PK_OrgNode”。无法在对象“dbo.#Org”中插入重复键。重复键值为 (0x)。语句已终止。”

表示您已向层次结构提供了多个根节点。主键将 OrgNode 限制为唯一值。如果这是预期的结果,您需要做的就是从 OrgNode 中删除主键约束并在应用程序级别强制执行树。

see this post for info on how to do so


但是,如果单个根节点是所需的结果,那么我们需要深入研究您正在使用的数据。

最终命令中插入的数据如下所示:

path    ChildID ParentID
0x      1       0
0x      1       2
0x      1       4

您可能在初始表中翻转了 Child 和 ParentId。基于提供给#tmpEntity 的数据的树不是由单个父级分支到子级,而是如下所示。

3   8     6
 \ /     /
  4  0  2
   \ | /
     1

如果您是目标树,则改为:

     0  
     | 
     1
    / \
   2   4
  /   / \  
 6   3   8

您的初始数据必须组织为:

ParentID ChildID 
0        1
1        2
4        3
1        4
2        6
4        8

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-09
    • 2021-05-08
    • 2019-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多