【发布时间】:2023-04-08 14:01:01
【问题描述】:
我在 SQL Server 2017 中有一个递归 WITH 查询:
;WITH rec AS (
SELECT
col1 AS root_order
,col1
,col2
,col3
,col4
,col5
,col6
,col7
,col8
,col9
FROM
TableA
UNION ALL
SELECT
rec.root_order,
TableA.col2,
TableA.col3,
TableA.col4,
TableA.col5,
TableA.col6,
TableA.col7,
TableA.col8,
TableA.col9,
rec.the_level
FROM
rec
INNER JOIN TableA on rec.Details = TableA.Orders
)
SELECT DISTINCT * FROM rec
这会产生:The statement terminated. The maximum recursion 100 has been exhausted before statement completion. 错误。
我尝试过:
OPTION (maxrecursion 0) 让它继续。但是当我这样做时,查询会无限循环,所以这不起作用。
在 Oracle 中,我可以使用 CONNECT BY ROOT 和 CONNECT BY PRIOR 和 NOCYCLE,但我知道 SQL Server 中没有类似的东西。所以我找到了this MSDN link,它暗示了某种形式:
with hierarchy
as
(
select
child,
parent,
0 as cycle,
CAST('.' as varchar(max)) + LTRIM(child) + '.' as [path]
from
#hier
where
parent is null
union all
select
c.child,
c.parent,
case when p.[path] like '%.' + LTRIM(c.child) + '.%' then 1 else 0 end as cycle,
p.[path] + LTRIM(c.child) + '.' as [path]
from
hierarchy as p
inner join
#hier as c
on p.child = c.parent
and p.cycle = 0
)
select
child,
parent,
[path]
from
hierarchy
where
cycle = 1;
go
用于寻找循环(或避免循环)。我似乎无法接受当前的查询并以这种方式对其进行编辑。如何编辑我当前的 SQL 以执行 MSDN 文章中的循环引用检测?
SQL FIDDLE 中要求的一些示例数据。
【问题讨论】:
-
SQL Server 不实现循环检测,这与 Oracle 或 DB2 不同。除了
UNION ALL之外,PostgreSQL 通过实现UNION有一种更平淡无奇的方式。您可能需要编写一个过程。 -
不需要写程序。只需保留迄今为止遇到的完整路径的分隔列表,并检查您是否不打算加入路径中已包含的项目。即您已经找到的方法
-
我认为我发布的 MSDN(以及其他类似的 dba.stackexchange.com/questions/162298/…)表明这是可能的。我正在努力解决的问题,可能是因为我不能很好地编写 SQL,是如何用我的代码更改他们的示例,这就是我发布的原因,作为在 Stack Overflow 上的 SQL Server 中执行此操作的示例。
-
你能给我一些示例数据吗?它不需要包含所有列。我只是想确定我了解您的需求。
-
我可以试试。我需要欺骗它。问题是我不知道数据在哪里是循环,这就是我需要这个查询的原因。我只是有很多列的大桌子。
标签: sql sql-server recursion ssms-2017