简体   繁体   English

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

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

I am having trouble converting a current ORACLE script across to an equivalent MS SQL Server version equivalent - so as to achieve the same functionality. 我无法将当前的ORACLE脚本转换为等效的MS SQL Server版本,以实现相同的功能。

All of the research I have done points me to a CTE as the only solution, and I have got that mostly working. 我所做的所有研究都指出,CTE是唯一的解决方案,而我所做的大部分都是有效的。 The only remaining issue is that the sequence is not correct - by that I therefore mean the 'hierarchy' does not come out correctly. 唯一剩下的问题是顺序不正确-因此,我的意思是“层次结构”没有正确显示。 I have tried using ORDER BY to get the result set into line, then tried ROW_NUMBER() etc, but none of these approaches quite work either. 我尝试使用ORDER BY将结果集放入行中,然后尝试ROW_NUMBER()等,但是这些方法都无法正常工作。 I think the main issue is that the script is not parsing up and down the levels in the same way the Oracle script does - and me then trying to 'correct' that after the CTE has completed is digging me into a deeper hole. 我认为主要的问题是该脚本没有像Oracle脚本那样在上下层次上进行解析-然后我试图“更正”在CTE完成之后,这使我陷入了更深的洞里。

Here are the 2 scripts below; 这是下面的两个脚本;

CURRENT ORACLE SQL SCRIPT VERSION (works perfectly) 当前的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 

MY MS SQL SERVER VERSION WIP ATTEMPT (SQL 2012 IS THE TARGET VERSION) 我的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'

I have tried a few other attempts and basically keep coming back to the same result. 我尝试了一些其他尝试,并且基本上保持相同的结果。 These queries run over a TRIM database and are supposed to list out the Hierarchy of 'Locations' by navigating down thru lrlocuri1 and lrlocuri2, for example like as below; 这些查询在TRIM数据库上运行,并且应该通过在lrlocuri1和lrlocuri2中进行导航来列出“位置”的层次结构,例如,如下所示;

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

etc 等等

Oracle by definition returns hierarchical datasets in depth first order. 根据定义,Oracle按深度优先顺序返回层次结构数据集。 Thererfore your ordering here is correct (eg https://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm ). 因此,您在这里的订购是正确的(例如https://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm )。

SqlServer on the other hand does not have this resultset ordering. 另一方面,SqlServer没有此结果集排序。 You have to order the data rows yourself. 您必须自己订购数据行。 My solution is to build for each row a hierarchical path value to sort after the data is selected. 我的解决方案是为每行构建一个分层的路径值,以在选择数据后进行排序。 If you have an id value for each row, something like this 如果每一行都有一个id值,则类似这样

parent-id / child-id

Here is a good example of it: Controlling the sibling order under recursive CTE? 这是一个很好的例子: 在递归CTE下控制同级顺序吗? (Look at column path ). (查看列路径 )。

If there are other solutions for SQLServer possible, mainly for more recent versions of it, I would be very interested to know. 如果还有其他针对SQLServer的解决方案(主要是针对SQLServer的最新版本),我将非常感兴趣。

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

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