Oracle SQL:"missing keyword" 将 SELECT INTO 与递归 CTE 结合使用时
Oracle SQL: "missing keyword" when using SELECT INTO with a recursive CTE
在存储过程中,我试图根据通过 WITH 和递归 CTE 语句创建的虚拟数据集设置声明的 varchar(100) 变量的值 'my_path'。
首先我尝试 "SELECT INTO",但出现 "missing keyword" 错误。
我也可以考虑从 WITH 语句中更新值为 'path' 的 table 行,但随后出现 "missing select keyword" 错误并且我明白我无法使用 CTE 进行更新在 Oracle SQL 服务器中。但是有没有办法访问递归 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;
我认为您的代码应该可以工作。它确实有一个挥之不去的右括号,这是可疑的。
也许一些简化会有所帮助:
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;
既然您已经修复了变量名...您仍然需要 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;
在存储过程中,我试图根据通过 WITH 和递归 CTE 语句创建的虚拟数据集设置声明的 varchar(100) 变量的值 'my_path'。
首先我尝试 "SELECT INTO",但出现 "missing keyword" 错误。
我也可以考虑从 WITH 语句中更新值为 'path' 的 table 行,但随后出现 "missing select keyword" 错误并且我明白我无法使用 CTE 进行更新在 Oracle SQL 服务器中。但是有没有办法访问递归 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;
我认为您的代码应该可以工作。它确实有一个挥之不去的右括号,这是可疑的。
也许一些简化会有所帮助:
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;
既然您已经修复了变量名...您仍然需要 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;