Oracle SQL:"缺少关键字"使用带有递归CTE的SELECT INTO时

时间:2018-01-18 11:09:25

标签: sql oracle select-into

在存储过程中,我试图设置声明的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;

2 个答案:

答案 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;