CTE 进入无限循环?
CTE goes in infinite loop?
我有一个这样的table结构
我想在 if(text_id = new_text_id)
之前重复出现的地方。
因此,假设我使用 CTE 将 1 作为 text_id
传递给 return 5
作为 text_id
。
我试过了,但它进入了无限循环,仍然尝试了 maxrecursion
WITH textHierarchy AS (
SELECT tm.text_id
FROM text_master tm
WHERE tm.text_id = 1
UNION ALL
SELECT tm.text_id
FROM text_master as tm
JOIN textHierarchy AS txtHr ON tm.text_id = txtHr.new_text_id -- Terminating Condition
WHERE txtHr.new_text_id IS NOT NULL
)
SELECT * FROM textHierarchy option (maxrecursion 5);
请告诉我我做错了什么。
我的目标是在数据库函数中使用此 CTE,并从 Java 调用该函数。
并且可以在函数内部使用 CTE。如果有怎么办?
你说的终止条件不是那个。这是一个连接条件,它定义了当前迭代与下一个迭代之间的关系。
我想你想要:
WITH textHierarchy AS (
SELECT tm.text_id
FROM text_master tm
WHERE tm.text_id = 1
UNION ALL
SELECT tm.text_id
FROM text_master as tm
JOIN textHierarchy AS txtHr ON tm.text_id = txtHr.new_text_id
WHERE txtHr.text_id <> txtHr.new_text_id -- Termination condition
)
SELECT * FROM textHierarchy option (maxrecursion 5);
你能试试下面的查询吗?我通过了 text_id=1
;WITH Numbers(text_id) AS
(
SELECT text_id
from rectab
where text_id=1
UNION ALL
SELECT text_id
FROM rectab
WHERE text_id=new_text_id
)
SELECT text_id
FROM Numbers;
create table dbo.text_master_test
(
text_id int,
text_details nvarchar(max),
new_text_id int
)
go
insert into text_master_test
values(1, 'det 1',2), (2, 'det 2',3), (3, 'det 3',4), (4, 'det 4',5), (5, 'det 5',5);
go
WITH textHierarchy AS (
SELECT tm.text_id, tm.new_text_id, nullif(tm.new_text_id, tm.text_id) as next_text_id
FROM text_master_test tm
WHERE tm.text_id = 1
UNION ALL
SELECT tm.text_id, tm.new_text_id, nullif(tm.new_text_id, tm.text_id) as next_text_id
FROM text_master_test as tm
JOIN textHierarchy AS txtHr ON tm.text_id = txtHr.next_text_id
)
SELECT * FROM textHierarchy;
go
create function dbo.textrecursion(@start_text_id int)
returns table
as
return
(
WITH textHierarchy
AS
(
SELECT tm.text_id, tm.text_details, tm.new_text_id,
nullif(tm.new_text_id, tm.text_id) as next_text_id
FROM dbo.text_master_test tm
WHERE tm.text_id = @start_text_id
UNION ALL
SELECT tm.text_id, tm.text_details, tm.new_text_id,
nullif(tm.new_text_id, tm.text_id) as next_text_id
FROM dbo.text_master_test as tm
JOIN textHierarchy AS txtHr ON tm.text_id = txtHr.next_text_id
)
select text_id, text_details, new_text_id
from textHierarchy
);
go
select *
from dbo.textrecursion(1)
select *
from dbo.textrecursion(4)
select *
from dbo.textrecursion(5)
go
drop function dbo.textrecursion;
go
drop table dbo.text_master_test
go
我有一个这样的table结构
我想在 if(text_id = new_text_id)
之前重复出现的地方。
因此,假设我使用 CTE 将 1 作为 text_id
传递给 return 5
作为 text_id
。
我试过了,但它进入了无限循环,仍然尝试了 maxrecursion
WITH textHierarchy AS (
SELECT tm.text_id
FROM text_master tm
WHERE tm.text_id = 1
UNION ALL
SELECT tm.text_id
FROM text_master as tm
JOIN textHierarchy AS txtHr ON tm.text_id = txtHr.new_text_id -- Terminating Condition
WHERE txtHr.new_text_id IS NOT NULL
)
SELECT * FROM textHierarchy option (maxrecursion 5);
请告诉我我做错了什么。
我的目标是在数据库函数中使用此 CTE,并从 Java 调用该函数。
并且可以在函数内部使用 CTE。如果有怎么办?
你说的终止条件不是那个。这是一个连接条件,它定义了当前迭代与下一个迭代之间的关系。
我想你想要:
WITH textHierarchy AS (
SELECT tm.text_id
FROM text_master tm
WHERE tm.text_id = 1
UNION ALL
SELECT tm.text_id
FROM text_master as tm
JOIN textHierarchy AS txtHr ON tm.text_id = txtHr.new_text_id
WHERE txtHr.text_id <> txtHr.new_text_id -- Termination condition
)
SELECT * FROM textHierarchy option (maxrecursion 5);
你能试试下面的查询吗?我通过了 text_id=1
;WITH Numbers(text_id) AS
(
SELECT text_id
from rectab
where text_id=1
UNION ALL
SELECT text_id
FROM rectab
WHERE text_id=new_text_id
)
SELECT text_id
FROM Numbers;
create table dbo.text_master_test
(
text_id int,
text_details nvarchar(max),
new_text_id int
)
go
insert into text_master_test
values(1, 'det 1',2), (2, 'det 2',3), (3, 'det 3',4), (4, 'det 4',5), (5, 'det 5',5);
go
WITH textHierarchy AS (
SELECT tm.text_id, tm.new_text_id, nullif(tm.new_text_id, tm.text_id) as next_text_id
FROM text_master_test tm
WHERE tm.text_id = 1
UNION ALL
SELECT tm.text_id, tm.new_text_id, nullif(tm.new_text_id, tm.text_id) as next_text_id
FROM text_master_test as tm
JOIN textHierarchy AS txtHr ON tm.text_id = txtHr.next_text_id
)
SELECT * FROM textHierarchy;
go
create function dbo.textrecursion(@start_text_id int)
returns table
as
return
(
WITH textHierarchy
AS
(
SELECT tm.text_id, tm.text_details, tm.new_text_id,
nullif(tm.new_text_id, tm.text_id) as next_text_id
FROM dbo.text_master_test tm
WHERE tm.text_id = @start_text_id
UNION ALL
SELECT tm.text_id, tm.text_details, tm.new_text_id,
nullif(tm.new_text_id, tm.text_id) as next_text_id
FROM dbo.text_master_test as tm
JOIN textHierarchy AS txtHr ON tm.text_id = txtHr.next_text_id
)
select text_id, text_details, new_text_id
from textHierarchy
);
go
select *
from dbo.textrecursion(1)
select *
from dbo.textrecursion(4)
select *
from dbo.textrecursion(5)
go
drop function dbo.textrecursion;
go
drop table dbo.text_master_test
go