在存储过程中,我试图设置声明的varchar(100)变量的值' my_path'基于通过WITH和递归CTE语句创建的虚拟数据集。
首先我尝试了#34; SELECT INTO",但得到了#34;缺少关键字"错误。
我可以考虑更新一个值为' path'来自WITH语句,但后来我得到了#34;缺少select keyword"错误,我已经明白我无法在Oracle SQL Server中使用CTE进行更新。但有没有办法访问递归CTE的输出呢?我稍后需要在我的存储过程中使用它。
declare mypath varchar(100);
begin
with CTE (toN,path,done)
as
(
-- anchor
select
cap.toN,
concat(concat(CAST(cap.fromN as varchar(10)) , ',') , CAST(cap.toN as varchar(10))),
case when cap.toN = 10000 then 1 else 0 end
from cap
where
(fromN = 1) and (cap.cap_up > 0)
union all
-- recursive
select
cap.toN,
concat(concat(path,','), CAST(cap.toN as varchar(10)) ),
case when cap.toN=10000 then 1 else 0 end
from cap join cte on
cap.fromN = cte.toN
where
(cap.cap_up > 0) and (cte.done = 0)
)
select path into mypath from cte where done=1
);
end;
答案 0 :(得分:1)
我认为你的代码应该有效。它确实有一个挥之不去的关闭,这是可疑的。
也许一些简化会有所帮助:
with CTE(toN, path, done) as (
-- anchor
select cap.toN, cap.fromN || ',' || cap.toN
(case when cap.toN = 10000 then 1 else 0 end)
from cap
where fromN = 1 and cap.cap_up > 0
union all
-- recursive
select cap.toN, path || ',' || cap.toN,
(case when cap.to = 10000 then 1 else 0 end)
from cap join
cte
on cap.fromN = cte.toN
where cap.cap_up > 0 and cte.done = 0
)
select path into my_path
from cte
where done = 1;
答案 1 :(得分:1)
现在你已经修复了变量名......你仍然需要第三列让CTE包含toN
,它位于查询递归部分的连接条件中。在查询结束时还有一个尾随)
括号,您可以使用||
来连接字符串(您不需要将其转换为varchars)。
WITH CTE (path,done, toN) as (
-- anchor
SELECT fromN || ',' || toN,
CASE WHEN toN = 10000 THEN 1 ELSE 0 END,
toN
FROM cap
WHERE "FROM" = 1
AND cap_up > 0
UNION ALL
-- recursive
SELECT cte.path || ',' || cap.toN,
CASE WHEN cap.toN =10000 THEN 1 ELSE 0 END,
cap.toN
FROM cap
join cte
on ( cap.fromN = cte.toN )
WHERE cap.cap_up > 0
AND cte.done = 0)
)
select path into my_path from cte where done=1;
更简单的解决方案是使用分层查询。
SELECT SUBSTR( SYS_CONNECT_BY_PATH( fromN, ',' ), 2 ) || ',' || toN
INTO mypath
FROM cap
WHERE toN = 10000
START WITH fromN = 1
CONNECT BY PRIOR toN = fromN;