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;