ORA-06511:PL/SQL游标已打开

ORA-06511:PL/SQL游标已打开,sql,oracle,plsql,cursor,Sql,Oracle,Plsql,Cursor,有人知道为什么系统告诉我PAR_CUR已经开放了吗?在我添加最外层的游标dup_cur之前,一切都很正常,现在我遇到了这个错误。谢谢你的帮助。数据如下 错误报告: ORA-06511: PL/SQL: cursor already open ORA-06512: at line 18 ORA-06512: at line 61 06511. 00000 - "PL/SQL: cursor already open" *Cause: An attempt was made to open

有人知道为什么系统告诉我PAR_CUR已经开放了吗?在我添加最外层的游标dup_cur之前,一切都很正常,现在我遇到了这个错误。谢谢你的帮助。数据如下

错误报告:

ORA-06511: PL/SQL: cursor already open
ORA-06512: at line 18
ORA-06512: at line 61
06511. 00000 -  "PL/SQL: cursor already open"
*Cause:    An attempt was made to open a cursor that was already open.
*Action:   Close cursor first before reopening.
代码:

开始 打开dup_cur

    LOOP
        FETCH dup_cur INTO v_dup;
        EXIT WHEN dup_cur%NOTFOUND;

        SELECT Count(*)
        INTO   v_count
        FROM   regions
        WHERE  Upper(child_name) = Upper(v_child);

        SELECT Count(parent_name)
        INTO   v_parentcount
        FROM   regions
        WHERE  Upper(parent_name) = Upper(v_child);

        IF v_count > 0
            OR v_parentcount > 0 THEN
          SELECT Count(parent_name)
          INTO   v_count
          FROM   regions
          WHERE  Upper(child_name) = Upper(v_child);

          IF v_count > 0 THEN
            OPEN reg_cur;

            FETCH reg_cur INTO v_parent;

            dbms_output.Put_line('----- Begin Output -----');

            LOOP
                IF v_regionnumber < 2 THEN
                  dbms_output.Put_line('Line 1: (Region 1) '
                                       || Upper(v_child));

                  dbms_output.Put_line('Line 2: (Region 1) '
                                       || Upper(v_child)
                                       || ' --> '
                                       || '(Region 2) '
                                       || Upper (v_parent));
                END IF;

                OPEN par_cur;

                v_parent2 := v_parent;

                FETCH par_cur INTO v_parent;

                EXIT WHEN par_cur%NOTFOUND;

                v_regionnumber := v_regionnumber + 1;

                IF v_regionnumber = 2 THEN
                  dbms_output.Put_line('Line 3: '
                                       || '(Region 1) '
                                       || Upper(v_child)
                                       || ' --> '
                                       || '(Region 2) '
                                       || Upper(v_parent2)
                                       || ' --> '
                                       || '(Region 3) '
                                       || Upper(v_parent));
                ELSE
                  IF v_regionnumber = 3 THEN
                    dbms_output.Put_line('Line 4: '
                                         || '(Region 1) '
                                         || Upper(v_child)
                                         || ' --> '
                                         || '(Region 2) '
                                         || Upper(v_parent3)
                                         || ' --> '
                                         || '(Region 3) '
                                         || Upper(v_parent2)
                                         || ' --> '
                                         || '(Region 4) '
                                         || Upper(v_parent));
                  END IF;
                END IF;

                CLOSE par_cur;

                v_parent3 := v_parent2;
            END LOOP;

            dbms_output.Put_line('----- End_Output -----');

            CLOSE reg_cur;
          ELSE
            dbms_output.Put_line('----- Begin Output -----'
                                 || Chr(10)
                                 || 'Line 1: (Region 1) '
                                 || Upper(v_child)
                                 || Chr(10)
                                 || '----- End_Output -----');
          END IF;
        ELSE
          dbms_output.Put_line('----- Begin Output -----'
                               || Chr(10)
                               || Upper(v_child)
                               ||' is not in the table.'
                               || Chr(10)
                               || '----- End_Output -----');
        END IF;
    END LOOP;

    CLOSE dup_cur;
END; 




CREATE TABLE regions
(
        PARENT_NAME     VARCHAR2(30),
        CHILD_NAME      VARCHAR2(30)
);
INSERT INTO regions VALUES('Texas','Rockford');
INSERT INTO regions VALUES('Colorado','Aurora');
INSERT INTO regions VALUES(NULL,'Asia');
INSERT INTO regions VALUES(NULL,'Australia');
INSERT INTO regions VALUES(NULL,'Europe');
INSERT INTO regions VALUES(NULL,'North America');
INSERT INTO regions VALUES('Asia','China');
INSERT INTO regions VALUES('Asia','Japan');
INSERT INTO regions VALUES('Australia','New South Wales');
INSERT INTO regions VALUES('New South Wales','Sydney');
INSERT INTO regions VALUES('Canada','Ontario');
INSERT INTO regions VALUES('China','Beijing');
INSERT INTO regions VALUES('England','London');
INSERT INTO regions VALUES('Europe','United Kingdom');
INSERT INTO regions VALUES('Illinois','Aurora');
INSERT INTO regions VALUES('Illinois','Chicago');
INSERT INTO regions VALUES('Illinois','Rockford');
INSERT INTO regions VALUES('Wisconsin','Madison'); 
INSERT INTO regions VALUES('Japan','Osaka');
INSERT INTO regions VALUES('Japan','Tokyo');
INSERT INTO regions VALUES('North America','Canada');
INSERT INTO regions VALUES('North America','United States');
INSERT INTO regions VALUES('Ontario','Ottawa');
INSERT INTO regions VALUES('Ontario','Toronto');
INSERT INTO regions VALUES('United States','Colorado');
INSERT INTO regions VALUES('United States','Illinois');
INSERT INTO regions VALUES('United States','Texas');
INSERT INTO regions VALUES('United Kingdom','England'); 
COMMIT;

您正在循环中打开和关闭光标。您应该在循环外部打开和关闭它


通常建议在打开任何游标时使用此语法

IF reg_cur %ISOPEN THEN
     CLOSE reg_cur ;
   END IF;
   OPEN reg_cur ;
希望这将有助于

FETCH REG_CUR INTO V_PARENT;
DBMS_OUTPUT.PUT_LINE('----- Begin Output -----');
OPEN PAR_CUR; -- ************OPEN HERE 
LOOP
  IF V_REGIONNUMBER < 2 THEN
    DBMS_OUTPUT.PUT_LINE('Line 1: (Region 1) ' || UPPER(V_CHILD));
    DBMS_OUTPUT.PUT_LINE('Line 2: (Region 1) ' || UPPER(V_CHILD) || ' --> ' || '(Region 2) ' || UPPER (V_PARENT));
  END IF;
  V_PARENT2 := V_PARENT;
  FETCH PAR_CUR INTO V_PARENT;
  EXIT WHEN PAR_CUR%NOTFOUND;
  V_REGIONNUMBER   := V_REGIONNUMBER + 1;
  IF V_REGIONNUMBER =2 THEN
    DBMS_OUTPUT.PUT_LINE('Line 3: ' || '(Region 1) '|| UPPER(V_CHILD) || ' --> ' || '(Region 2) ' || UPPER(V_PARENT2) || ' --> ' || '(Region 3) ' || UPPER(V_PARENT));
  ELSE
    IF V_REGIONNUMBER =3 THEN
      DBMS_OUTPUT.PUT_LINE('Line 4: ' || '(Region 1) '|| UPPER(V_CHILD) || ' --> ' || '(Region 2) ' || UPPER(V_PARENT3) || ' --> ' || '(Region 3) ' || UPPER(V_PARENT2)|| ' --> ' || '(Region 4) ' || UPPER(V_PARENT));
    END IF;
  END IF;
  V_PARENT3 := V_PARENT2;
END LOOP;
CLOSE PAR_CUR;-- ************CLOSE HERE
SQL> select ltrim(str, ' --> ') str
  2    from (select child_name, level, SYS_CONNECT_BY_PATH('(Region ' || level || ') ' || child_name, ' --> ') str,
  3                 parent_name
  4            from regions
  5           start with child_name = 'Rockford'
  6           connect by  child_name = prior parent_name)
  7   where parent_name is null
  8  /

STR
--------------------------------------------------------------------------------
(Region 1) Rockford --> (Region 2) Illinois --> (Region 3) United States --> (Re
gion 4) North America

(Region 1) Rockford --> (Region 2) Texas --> (Region 3) United States --> (Regio
n 4) North America


SQL> select ltrim(str, ' --> ') str
  2    from (select child_name, level, SYS_CONNECT_BY_PATH('(Region ' || level || ') ' || child_name, ' --> ') str,
  3                 parent_name
  4            from regions
  5           start with child_name = 'London'
  6           connect by  child_name = prior parent_name)
  7   where parent_name is null
  8  /

STR
--------------------------------------------------------------------------------
(Region 1) London --> (Region 2) England --> (Region 3) United Kingdom --> (Regi
on 4) Europe


SQL>
IF reg_cur %ISOPEN THEN
     CLOSE reg_cur ;
   END IF;
   OPEN reg_cur ;