Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 使用ORA-32042递归获取SYS_REFCURSOR_Sql_Oracle_Plsql_Cursor - Fatal编程技术网

Sql 使用ORA-32042递归获取SYS_REFCURSOR

Sql 使用ORA-32042递归获取SYS_REFCURSOR,sql,oracle,plsql,cursor,Sql,Oracle,Plsql,Cursor,我有一个定义如下的表: 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,

我有一个定义如下的表:

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;
我有两种类型(HTHIS仅供参考。我尽可能简化了示例!):

从SYS_REFCURSOR打印内容的包(例如,返回一些伪数据):

我试过这个:

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:“打印信息”第9行

ORA-06512:第17行

但是当我将代码从光标开始注释到光标结束

-- 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
很好用! 如果注释第一次查询并取消注释第二次查询,则再次正常工作!
我不明白哪里出了问题

光标表达式+ANSI->native转换是一个bug

您的案例可以简化为一条SQL语句

SQL> select cursor(with t1(p, c) as (select distinct null p, t.p as c
  2                                    from my_tab t
  3                                  union all
  4                                  select t.p, t.c
  5                                    from t1
  6                                    join my_tab t
  7                                      on t.p = t1.c)
  8           select p || c from t1) c from dual;
select cursor(with t1(p, c) as (select distinct null p, t.p as c
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-32042: recursive WITH clause must reference itself directly in one of the
UNION ALL branches


SQL> select * from table(dbms_xplan.display_cursor(format => 'basic'));

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
EXPLAINED SQL STATEMENT:
------------------------
select 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) c from dual

Plan hash value: 956860371

------------------------------------------------------------
| Id  | Operation                                 | Name   |
------------------------------------------------------------
|   0 | SELECT STATEMENT                          |        |
|   1 |  VIEW                                     |        |
|   2 |   UNION ALL (RECURSIVE WITH) BREADTH FIRST|        |
|   3 |    SORT UNIQUE                            |        |
|   4 |     TABLE ACCESS FULL                     | MY_TAB |
|   5 |    VIEW                                   |        |
|   6 |     HASH JOIN                             |        |
|   7 |      RECURSIVE WITH PUMP                  |        |
|   8 |      TABLE ACCESS FULL                    | MY_TAB |
|   9 |  FAST DUAL                                |        |
------------------------------------------------------------


26 rows selected.

SQL> select cursor(with t1(p, c) as (select distinct null p, t.p as c
  2                                    from my_tab t
  3                                  union all
  4                                  select t.p, t.c
  5                                    from t1, my_tab t
  6                                   where t.p = t1.c)
  7           select p || c from t1) c from dual;

C
--------------------
CURSOR STATEMENT : 1

CURSOR STATEMENT : 1

P|
--
1
8
7
4
12
13
42
45
46
73
84
42
45
46

14 rows selected.


SQL> select * from table(dbms_xplan.display_cursor(format => 'basic'));

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
EXPLAINED SQL STATEMENT:
------------------------
select 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, my_tab t
where t.p = t1.c)          select p || c from t1) c from dual

Plan hash value: 2529699678

------------------------------------------------------------
| Id  | Operation                                 | Name   |
------------------------------------------------------------
|   0 | SELECT STATEMENT                          |        |
|   1 |  VIEW                                     |        |
|   2 |   UNION ALL (RECURSIVE WITH) BREADTH FIRST|        |
|   3 |    SORT UNIQUE                            |        |
|   4 |     TABLE ACCESS FULL                     | MY_TAB |
|   5 |    HASH JOIN                              |        |
|   6 |     RECURSIVE WITH PUMP                   |        |
|   7 |     TABLE ACCESS FULL                     | MY_TAB |
|   8 |  FAST DUAL                                |        |
------------------------------------------------------------


24 rows selected.
因此,第一个查询(使用ANSI连接语法)失败,而第二个查询(使用本机连接语法)成功完成

查询计划中的差异在于第一次查询的查看操作(ID=5)。 它告诉我们,内联视图是在查询转换期间创建的

让我们看看事件10053跟踪文件中的转换查询

select cursor(with "T1"("P", "C")
              as((select "from$_subquery$_004"."QCSJ_C000000000400001_2" "P",
                         "from$_subquery$_004"."QCSJ_C000000000400003_3" "C"
                    from (select "T1"."P" "QCSJ_C000000000400000",
                                 "T1"."C" "QCSJ_C000000000400002",
                                 "T"."P"  "QCSJ_C000000000400001_2",
                                 "T"."C"  "QCSJ_C000000000400003_3"
                            from "T1" "T1", "MY_TAB" "T"
                           where "T"."P" = "T1"."C") "from$_subquery$_004")
                 union all (select distinct null "P", "T"."P" "C"
                    from "MY_TAB" "T")) select "T1"."P" || "T1"."C"
              "P||C" from "T1" "T1") "C"
  from "SYS"."DUAL" "DUAL"

select cursor(with "T1"("P", "C")
              as((select "T"."P" "P", "T"."C" "C"
                    from "T1" "T1", "MY_TAB" "T"
                   where "T"."P" = "T1"."C") union all
                 (select distinct null "P", "T"."P" "C"
                    from "MY_TAB" "T")) select "T1"."P" || "T1"."C"
              "P||C" from "T1" "T1") "C"
  from "SYS"."DUAL" "DUAL"

您可以看到,在第一次查询中,join已被转换为带有where子句的附加内联视图,如果您尝试运行第一次查询,ORA-32042将失败。

我觉得这似乎是一个bug;对于递归with子句查询没有任何限制。我的Oracle支持中也没有关于该错误的内容,因此如果可以的话,您可能会收到一个服务请求。
SQL> select cursor(with t1(p, c) as (select distinct null p, t.p as c
  2                                    from my_tab t
  3                                  union all
  4                                  select t.p, t.c
  5                                    from t1
  6                                    join my_tab t
  7                                      on t.p = t1.c)
  8           select p || c from t1) c from dual;
select cursor(with t1(p, c) as (select distinct null p, t.p as c
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-32042: recursive WITH clause must reference itself directly in one of the
UNION ALL branches


SQL> select * from table(dbms_xplan.display_cursor(format => 'basic'));

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
EXPLAINED SQL STATEMENT:
------------------------
select 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) c from dual

Plan hash value: 956860371

------------------------------------------------------------
| Id  | Operation                                 | Name   |
------------------------------------------------------------
|   0 | SELECT STATEMENT                          |        |
|   1 |  VIEW                                     |        |
|   2 |   UNION ALL (RECURSIVE WITH) BREADTH FIRST|        |
|   3 |    SORT UNIQUE                            |        |
|   4 |     TABLE ACCESS FULL                     | MY_TAB |
|   5 |    VIEW                                   |        |
|   6 |     HASH JOIN                             |        |
|   7 |      RECURSIVE WITH PUMP                  |        |
|   8 |      TABLE ACCESS FULL                    | MY_TAB |
|   9 |  FAST DUAL                                |        |
------------------------------------------------------------


26 rows selected.

SQL> select cursor(with t1(p, c) as (select distinct null p, t.p as c
  2                                    from my_tab t
  3                                  union all
  4                                  select t.p, t.c
  5                                    from t1, my_tab t
  6                                   where t.p = t1.c)
  7           select p || c from t1) c from dual;

C
--------------------
CURSOR STATEMENT : 1

CURSOR STATEMENT : 1

P|
--
1
8
7
4
12
13
42
45
46
73
84
42
45
46

14 rows selected.


SQL> select * from table(dbms_xplan.display_cursor(format => 'basic'));

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
EXPLAINED SQL STATEMENT:
------------------------
select 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, my_tab t
where t.p = t1.c)          select p || c from t1) c from dual

Plan hash value: 2529699678

------------------------------------------------------------
| Id  | Operation                                 | Name   |
------------------------------------------------------------
|   0 | SELECT STATEMENT                          |        |
|   1 |  VIEW                                     |        |
|   2 |   UNION ALL (RECURSIVE WITH) BREADTH FIRST|        |
|   3 |    SORT UNIQUE                            |        |
|   4 |     TABLE ACCESS FULL                     | MY_TAB |
|   5 |    HASH JOIN                              |        |
|   6 |     RECURSIVE WITH PUMP                   |        |
|   7 |     TABLE ACCESS FULL                     | MY_TAB |
|   8 |  FAST DUAL                                |        |
------------------------------------------------------------


24 rows selected.
select cursor(with "T1"("P", "C")
              as((select "from$_subquery$_004"."QCSJ_C000000000400001_2" "P",
                         "from$_subquery$_004"."QCSJ_C000000000400003_3" "C"
                    from (select "T1"."P" "QCSJ_C000000000400000",
                                 "T1"."C" "QCSJ_C000000000400002",
                                 "T"."P"  "QCSJ_C000000000400001_2",
                                 "T"."C"  "QCSJ_C000000000400003_3"
                            from "T1" "T1", "MY_TAB" "T"
                           where "T"."P" = "T1"."C") "from$_subquery$_004")
                 union all (select distinct null "P", "T"."P" "C"
                    from "MY_TAB" "T")) select "T1"."P" || "T1"."C"
              "P||C" from "T1" "T1") "C"
  from "SYS"."DUAL" "DUAL"

select cursor(with "T1"("P", "C")
              as((select "T"."P" "P", "T"."C" "C"
                    from "T1" "T1", "MY_TAB" "T"
                   where "T"."P" = "T1"."C") union all
                 (select distinct null "P", "T"."P" "C"
                    from "MY_TAB" "T")) select "T1"."P" || "T1"."C"
              "P||C" from "T1" "T1") "C"
  from "SYS"."DUAL" "DUAL"