繁体   English   中英

将ORACLE层次结构START WITH / CONNECT BY PRIOR转换为SQL Server CTE

[英]Converting ORACLE hierarchical START WITH / CONNECT BY PRIOR to SQL Server CTE

我无法将当前的ORACLE脚本转换为等效的MS SQL Server版本,以实现相同的功能。

我所做的所有研究都指出,CTE是唯一的解决方案,而我所做的大部分都是有效的。 唯一剩下的问题是顺序不正确-因此,我的意思是“层次结构”没有正确显示。 我尝试使用ORDER BY将结果集放入行中,然后尝试ROW_NUMBER()等,但是这些方法都无法正常工作。 我认为主要的问题是该脚本没有像Oracle脚本那样在上下层次上进行解析-然后我试图“更正”在CTE完成之后,这使我陷入了更深的洞里。

这是下面的两个脚本;

当前的Oracle SQL脚本版本(完美运行)

SELECT lpad('-',2*(level-2), '-') || l.lcname descr, r.lrlocuri1 id, l.lciswithin, l.lctype, 1 lcisactive, l.lcvalidto 
    FROM tslocrel r,  tslocation l WHERE l.uri=r.lrlocuri1
    AND level>1 AND level<6
    AND lctype=1 AND lcvalidto<'2' 
START WITH lrlocuri1=4485 CONNECT BY PRIOR lrlocuri1 = lrlocuri2 

我的MS SQL Server版本WIP尝试(SQL 2012是目标版本)

WITH locationCTE (lcname, lrlocuri1, lciswithin, lctype, lcisactive, lcvalidto, level) AS (

  SELECT l.lcname, r.lrlocuri1, l.lciswithin, l.lctype, 1 AS lcisactive, l.lcvalidto, 1 AS level
  FROM tslocrel r
  INNER JOIN tslocation l ON r.lrlocuri1 = l.uri
  AND r.lrlocuri1=4485

  UNION ALL

  SELECT l.lcname, r.lrlocuri1, l.lciswithin, l.lctype, 1 AS lcisactive, l.lcvalidto, cte.level + 1 AS level
  FROM tslocrel r
  INNER JOIN tslocation l ON r.lrlocuri1 = l.uri
  INNER JOIN locationCTE cte ON cte.lrlocuri1 = r.lrlocuri2

)

SELECT RIGHT(REPLICATE('-', 2*(level-2)) + LEFT('-', 2*(level-2)), 2*(level-2)) + lcname AS descr, lrlocuri1 id, lciswithin, lctype, lcisactive, 
lcvalidto
FROM locationCTE
WHERE level>1 AND level<6
AND lctype=1 AND lcvalidto<'2'

我尝试了一些其他尝试,并且基本上保持相同的结果。 这些查询在TRIM数据库上运行,并且应该通过在lrlocuri1和lrlocuri2中进行导航来列出“位置”的层次结构,例如,如下所示;

General Manager
  -Corporate Support
    --Customer Service
      --Xxxxxxx
      --Xxxxxxx
      (etc)
    --Finance
      --Xxxxx
  -Environment and Planning
    --Xxxxx
    --Xxxxx
  -Xxxxxxxxxxxx
    --Xxxxx
    --XXxxx

等等

根据定义,Oracle按深度优先顺序返回层次结构数据集。 因此,您在这里的订购是正确的(例如https://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm )。

另一方面,SqlServer没有此结果集排序。 您必须自己订购数据行。 我的解决方案是为每行构建一个分层的路径值,以在选择数据后进行排序。 如果每一行都有一个id值,则类似这样

parent-id / child-id

这是一个很好的例子: 在递归CTE下控制同级顺序吗? (查看列路径 )。

如果还有其他针对SQLServer的解决方案(主要是针对SQLServer的最新版本),我将非常感兴趣。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM