我有两个带有hierarchyid字段的表,其中一个是暂存表,包含需要合并到另一个表中的新数据(即一组需要添加到主树中的节点,其中某些节点可能已经存在)。
除了定义树结构(父/子关系)的hierarchyid列外,每个表都有一个单独的列,其中包含唯一标识每个节点的节点标识符。也就是说,判断暂存表中的节点是否已经存在于主表中的方法是通过节点ID而不是通过hierarchyid列。
实现上,需要执行以下处理:
重要的是,这种方法只有在分期表中的树以广度优先顺序排序/遍历时才能起作用-这样当遇到RS时,可以保证其父级PS已经在主表中具有相应的行。
到目前为止,我唯一看到的在SQL Server中实现这一点的方法是使用游标遍历分期表(已经排序),并为每一行调用一个存储过程,该存储过程基本上完全执行上述操作,包括使用SELECT MAX()查找已存在于PM下的最高层次结构ID,以便可以唯一地添加子项。
虽然这是一种效率极低的方法,但对于我的目的来说太慢了。有更好的方法吗?
背景是,这是我正在进行的可行性检查。我需要弄清楚是否可以在SQL Server内快速执行此操作。如果结果发现我不能这样做,我将不得不以其他方式在数据库外执行它。合并树是问题领域固有的(实际上,在某种意义上,它就是问题领域),因此不可能采用不同的数据结构或采用更广泛的视角,尝试以某种方式完全避免执行此操作。
更新
如请求所示,这里有一个具体的例子。
"分期"和"主"表都有相同的两列:
请注意,暂存表中层次ID为/1/1/的节点对应于目标表中层次ID为/1/2/的节点(这就是为什么节点ID很重要——不能仅复制层次ID值)。此外,请注意新的节点ID 6 被添加为正确父节点(节点ID为3),这也是为什么层次ID很重要的原因——它定义了任何新节点的树形结构(父子关系)。任何解决方案都需要考虑这两个方面。
除了定义树结构(父/子关系)的hierarchyid列外,每个表都有一个单独的列,其中包含唯一标识每个节点的节点标识符。也就是说,判断暂存表中的节点是否已经存在于主表中的方法是通过节点ID而不是通过hierarchyid列。
实现上,需要执行以下处理:
For each row, RS, in the staging table:
If there is not already a row with the same Id as RS in the main table:
Find the parent, PS, of the staging row
Find the row, PM, in the main table that has the same node ID as PS
Create a new child, RM of row PM
Set PM's ID equal to the ID of RS
重要的是,这种方法只有在分期表中的树以广度优先顺序排序/遍历时才能起作用-这样当遇到RS时,可以保证其父级PS已经在主表中具有相应的行。
到目前为止,我唯一看到的在SQL Server中实现这一点的方法是使用游标遍历分期表(已经排序),并为每一行调用一个存储过程,该存储过程基本上完全执行上述操作,包括使用SELECT MAX()查找已存在于PM下的最高层次结构ID,以便可以唯一地添加子项。
虽然这是一种效率极低的方法,但对于我的目的来说太慢了。有更好的方法吗?
背景是,这是我正在进行的可行性检查。我需要弄清楚是否可以在SQL Server内快速执行此操作。如果结果发现我不能这样做,我将不得不以其他方式在数据库外执行它。合并树是问题领域固有的(实际上,在某种意义上,它就是问题领域),因此不可能采用不同的数据结构或采用更广泛的视角,尝试以某种方式完全避免执行此操作。
更新
如请求所示,这里有一个具体的例子。
"分期"和"主"表都有相同的两列:
hierarchy_id of type hierarchyid
node_id of type bigint
初始内容
主函数:
hierarchy_id node_id
/1/ 1
/1/1/ 2
/1/2/ 3
/1/3/ 4
预发布环境:
hierarchy_id node_id
/1/ 1
/1/1/ 3
/1/2/ 5
/1/1/1/ 6
期望的内容
主要内容:
hierarchy_id node_id
/1/ 1
/1/1/ 2
/1/2/ 3
/1/3/ 4
/1/4/ 5
/1/2/1/ 6
请注意,暂存表中层次ID为/1/1/的节点对应于目标表中层次ID为/1/2/的节点(这就是为什么节点ID很重要——不能仅复制层次ID值)。此外,请注意新的节点ID 6 被添加为正确父节点(节点ID为3),这也是为什么层次ID很重要的原因——它定义了任何新节点的树形结构(父子关系)。任何解决方案都需要考虑这两个方面。