【发布时间】:2018-05-14 06:14:42
【问题描述】:
我有这样定义的表:
create table my_tab as
select '1' p, '2' c from dual
union
select '1' p, '3' c from dual
union
select '4' p, '5' c from dual
union
select '4' p, '6' c from dual
union
select '4' p, '2' c from dual
union
select '7' p, '3' c from dual
union
select '8' p, '4' c from dual;
我有两种类型(Тhis 仅供参考。我尽可能简化了示例!):
TYPE TObj_OUT AS OBJECT(File_Name VARCHAR2(128),
File_Records NUMBER,
Session_ID NUMBER,
Instanse_ID NUMBER);
CREATE OR REPLACE type TObj_OUT_NT AS TABLE OF TObj_OUT;
从 SYS_REFCURSOR 打印内容的包(例如返回一些虚拟数据):
CREATE OR REPLACE FUNCTION print_info(ip_Select IN SYS_REFCURSOR
) RETURN TObj_OUT_NT PIPELINED AS
TYPE TROW IS TABLE OF VARCHAR2(32767);
v_rows TROW;
BEGIN
LOOP
FETCH ip_Select BULK COLLECT INTO v_rows LIMIT 100;
FOR i IN 1 .. v_rows.COUNT LOOP
DBMS_OUTPUT.put_line(v_rows(i));
END LOOP;
EXIT WHEN ip_Select%NOTFOUND;
END LOOP;
CLOSE ip_Select;
PIPE ROW (TObj_OUT('bb', 0, 0, 5));
RETURN;
END print_info;
我试过这个:
declare
v_cnt number(8);
my_cursor SYS_REFCURSOR;
begin
open my_cursor for with t1(p,
c) as
(select distinct null p, t.p as c
from my_tab t
union all
select t.p, t.c
from t1
join my_tab t
on t.p = t1.c)
select p || c from t1;
SELECT file_records
into v_cnt
FROM TABLE(
print_info(
-- cursor start
cursor(
-- FIRST QUERY
with t1(p,
c) as
(select distinct null p, t.p as c
from my_tab t
union all
select t.p, t.c
from t1
join my_tab t
on t.p = t1.c)
select p || c from t1
--FIRST_QUERY END
--SECOND QUERY
--select p||c from my_tab
--SECONF QUERY END
)
-- cursor end
-- my_cursor
));
end;
当我执行块时,我收到此错误:
ORA-32042: 递归 WITH 子句必须直接在 UNION ALL 分支之一中引用自身
ORA-06512:在“PRINT_INFO”第 9 行
ORA-06512:第 17 行
但是当我从 cursor start 到 cursor end
注释代码时-- cursor start
cursor(with t1(p,
c) as
(select distinct null p, t.p as c
from my_tab t
union all
select t.p, t.c
from t1
join my_tab t
on t.p = t1.c)
select p || c from t1)
-- cursor end
并取消注释行
-- my_cursor
效果很好! 如果评论 FIRST QUERY 并取消评论 SECOND QUERY 它又可以正常工作了! 我不明白问题出在哪里!
【问题讨论】:
-
这对我来说似乎是一个错误; the documentation 中没有关于递归 with 子句查询的限制。 My Oracle Support 中也没有针对该错误的任何内容,因此如果可以的话,您可能应该提出服务请求。