【问题标题】:How to update a hierarchyid column如何更新hierarchyid列
【发布时间】:2019-03-12 06:57:20
【问题描述】:

我有一个名为items 的表,它有一个父/子关系,我将其转换为一个hierarchyid。

我已按照this 教程进行操作。

教程的所有步骤都有效,除了最后的更新语句。

我收到错误消息:

不允许从数据类型 hierarchyid 到 nvarchar(max) 的隐式转换。使用 CONVERT 函数运行此查询。

但这没有任何意义。我正在更新的字段是一个hierarchyid,而不是一个nvarchar(nax)。所以我看不到哪里涉及到 nvarchar(max) 字段。

drop table #children
CREATE TABLE #Children   
   (  
    ID int,  
    TenantId int,
    ParentID int,
    Num int  
);  
GO
CREATE CLUSTERED INDEX tmpind ON #Children(TenantId, ParentID, ID);  
GO

INSERT #Children (ID,  TenantId,ParentID, Num)  
SELECT ID, TenantId, ParentID, 
  ROW_NUMBER() OVER (PARTITION BY TenantId, ParentID ORDER BY ParentId)   
FROM Items  
GO 

SELECT * FROM #Children ORDER BY TenantId, ParentID, Num  
GO


WITH paths(path, ID, ParentId, TenantId)   
AS (  
-- This section provides the value for the root of the hierarchy  
SELECT hierarchyid::GetRoot() AS OrgNode, ID, ParentId, TenantId   
FROM #Children AS C   
WHERE ParentId IS NULL   

UNION ALL   
-- This section provides values for all nodes except the root  
SELECT   
CAST(p.path.ToString() + CAST(C.Num AS varchar(30)) + '/' AS hierarchyid),   
C.ID , C.ParentId, C.TenantId 
FROM #Children AS C   
JOIN paths AS p   
   ON C.ParentID = P.ID   
)
-- This select statement runs just fine and shows expected data.
--Select i.Id as ItemId, p.path, p.path.ToString() as LogicalNode, p.Id, p.ParentId, p.TenantId from Paths P
--join Items I on p.Id = i.Id
--order by P.TenantId, P.path

--Note that I have tried using the convert function, but it still fails with the same error message.
UPDATE I Set OrgNode = Convert(hierarchyid, P.path)
FROM Items I    
JOIN Paths AS P   
   ON I.ID = P.ID  
GO

编辑 奇怪的是,这个DBFiddle 有效。

【问题讨论】:

    标签: sql-server tsql sql-server-2012


    【解决方案1】:

    看起来OrgNode 列的类型不是hierachyid。你可以使用ToString()

    UPDATE I Set OrgNode = P.path.ToString()
    FROM Items I    
    JOIN Paths AS P   
       ON I.ID = P.ID 
    

    或更改表 Items 并更改列类型。

    【讨论】:

    • 我尝试使用上面的 ToString(),但它给出了相同的错误消息。并且 Items.OrgNode 是 hierarchyId 类型,从我添加的屏幕截图中可以看出。这就是为什么收到该错误消息如此奇怪的原因。
    • @Greg0 请在dbfiddle.uk 上发布可重现的代码,并带有单一数据记录。
    • 完成了,但奇怪的是,它在那里工作得很好。见上面的链接。
    • @Greg0 我建议为您的 SQL Server 版本安装最新的累积更新。
    • 我刚刚意识到发生了什么, - 此表上有一个触发器正在干扰进程。非常感谢您的帮助。
    【解决方案2】:

    看起来你解决了你的问题,但我建议将转换为 hierarchyid 保存到最后。像这样:

    WITH paths(path, ID, ParentId, TenantId)   
    AS (  
    -- This section provides the value for the root of the hierarchy  
    SELECT cast('/' as varchar(max)) AS OrgNode, ID, ParentId, TenantId   
    FROM #Children AS C   
    WHERE ParentId IS NULL   
    
    UNION ALL   
    -- This section provides values for all nodes except the root  
    SELECT   
    CAST(concat(p.path.ToString(), C.Num, '/') AS varchar(max)),   
    C.ID , C.ParentId, C.TenantId 
    FROM #Children AS C   
    JOIN paths AS p   
       ON C.ParentID = P.ID   
    )
    -- This select statement runs just fine and shows expected data.
    --Select i.Id as ItemId, p.path, p.path.ToString() as LogicalNode, p.Id, p.ParentId, p.TenantId from Paths P
    --join Items I on p.Id = i.Id
    --order by P.TenantId, P.path
    
    --Note that I have tried using the convert function, but it still fails with the same error message.
    UPDATE I Set OrgNode = Convert(hierarchyid, P.path)
    FROM Items I    
    JOIN Paths AS P   
       ON I.ID = P.ID  
    GO
    

    注意,我还更改了 concat() 函数的 + 连接样式,这样您就不必将C.Num 转换为 varchar。

    【讨论】:

      猜你喜欢
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多