过程(PL/SQL 包)中的“ORA-01001 无效游标”

Posted

技术标签:

【中文标题】过程(PL/SQL 包)中的“ORA-01001 无效游标”【英文标题】:"ORA-01001 invalid cursor" in procedure (PL/SQL package) 【发布时间】:2016-10-21 09:52:22 【问题描述】:

我正在开发一个 PL/SQL 包,并且刚刚完成了通用框架,以便进行第一次测试。

但是,我的程序中出现了一个奇怪的 ORA-01001 invalid cursor 错误,我似乎无法弄清楚。

任何想法可能对我的游标无效?两个游标的 SELECT 语句都返回值,我使用双引号对 "KEY""VALUE" 进行了转义以避免遇到保留字问题...

这是我的包体代码,提前感谢您的任何提示:

create or replace PACKAGE BODY MY_PP AS

  PROCEDURE my_proc(execProc IN NUMBER DEFAULT 1) IS

  cursor c_cursor1 is SELECT "KEY", "VALUE" FROM MY_TABLE_1;
  cursor c_cursor2 is SELECT "KEY", "VALUE"  FROM MY_TABLE_2;

  vc_my_variable1 VARCHAR2(100);
  vc_my_variable2 VARCHAR2(100);
  vc_my_variable3 VARCHAR2(100);
  vc_my_variable4 VARCHAR2(100);

  sql_query VARCHAR2(400);

  v_data_type VARCHAR2(100);

  BEGIN

  OPEN c_cursor1;
    LOOP

      FETCH c_cursor1 INTO vc_my_variable1, vc_my_variable2;
      EXIT WHEN c_cursor1%NOTFOUND;         

        SELECT DATA_TYPE INTO v_data_type FROM USER_TAB_COLS WHERE COLUMN_NAME = vc_my_variable1 AND TABLE_NAME = 'MY_TABLE_3';

        IF v_data_type = 'VARCHAR2' THEN
            sql_query := 'UPDATE MY_TABLE_3 SET :1 = :2;';
        END IF;


        IF v_data_type = 'NUMBER' THEN
            sql_query := 'UPDATE MY_TABLE_3 SET :1 = TO_NUMBER(:2);';
        END IF;

        EXECUTE IMMEDIATE sql_query USING vc_my_variable1, vc_my_variable2;




    END LOOP;

  CLOSE c_cursor1;


  OPEN c_cursor2;
    LOOP

      FETCH c_cursor2 INTO vc_my_variable3, vc_my_variable4;
      EXIT WHEN c_cursor2%NOTFOUND;

       SELECT "DATA_TYPE" INTO v_data_type FROM USER_TAB_COLS WHERE COLUMN_NAME = vc_my_variable3 AND TABLE_NAME = 'MY_TABLE_4';

        IF v_data_type = 'VARCHAR2' THEN
            sql_query := 'UPDATE MY_TABLE_4 SET :1 = :2;';
        END IF;


        IF v_data_type = 'NUMBER' THEN
            sql_query := 'UPDATE MY_TABLE_4 SET :1 = TO_NUMBER(:2);';
        END IF;

        EXECUTE IMMEDIATE sql_query USING vc_my_variable3, vc_my_variable4;




    END LOOP;

  CLOSE c_cursor2; 

  commit;

  END my_proc;

END MY_PP;

【问题讨论】:

您无法使用绑定变量重构查询。您只能绑定值,不能绑定列、表或任意关键字。 (这是迈克尔在聊天中告诉你的内容,但我在工作时无法访问。) 您不必区分 VARCHAR2 和 NUMBER - 这是绑定变量的一大优势。 sql_query := 'UPDATE MY_TABLE_3 SET '||vc_my_variable1||' = :2;' 在任何一种情况下都有效。 【参考方案1】:

编辑:我发现您的包裹中有一些错误

1) 你尝试更新

        sql_query := 'UPDATE MY_TABLE_3 SET :1 = :2;';

和 after 绑定例如 'col1' 和 'val2';它看起来像

UPDATE MY_TABLE_3 SET 'col1' = 'val2';

但是当您在执行立即语句中使用绑定变量时,您只发送文字。而且您不能用另一个字符串更新一个字符串。 如果要编写正确的更新,则应添加 SQL 注入;

        sql_query := 'UPDATE MY_TABLE_3 SET '||vc_my_variable1 ||' = :2;';
  ... 
  EXECUTE IMMEDIATE sql_query USING vc_my_variable2;

2) 下一个(完成

移动EXIT WHEN c_cursor1%NOTFOUND;

FETCH c_cursor1 INTO vc_my_variable1, vc_my_variable2;之后

3) 错误 ORA-01001 游标无效。如果您的 MAXOPENCURSORS 太小或必须使用 OLON 或 OLOGON 定义登录数据区 (LDA),则可能会出现。如果未定义 LDA,则会为以下调用发出此消息:OPEN、COM、CON、ROL 和 LOGOFF。 http://www.dba-oracle.com/t_ora_01001_invalid_cursor.htm.

【讨论】:

谢谢,刚刚做到了。不过没有变化,错误消息保持不变。 如果您从 SQLplus SELECT "KEY", "VALUE" FROM MY_TABLE_1;SELECT "KEY", "VALUE" FROM MY_TABLE_2 运行查询,请检查是否都执行了查询 是的,两者都可以在纯 SQL 中执行并返回我的测试数据。编辑:通过 SQLDeveloper 运行它,将通过 SQLPlus 运行它以确保。 Edit2:SQLPlus 也可以使用 我会试试,但是UPDATE语句不是游标的一部分?立即执行应该用我在ÙSING 部分中给出的值替换:1:2?为什么这不起作用(很确定我在其他软件包中做过几次?) 去掉动态语句末尾的分号,即sql_query := 'UPDATE MY_TABLE_3 SET '||vc_my_variable1 ||' = :2';

以上是关于过程(PL/SQL 包)中的“ORA-01001 无效游标”的主要内容,如果未能解决你的问题,请参考以下文章

奇怪的 PL SQL 无效游标

ORA-01001 无效游标错误

过程中出现奇怪的错误“Ora-01001 Invalid cursor”

循环退出条件中的“ORA-01001:无效游标”

第二次运行代码尝试后出现 ORA-01001

包括编写在不同文件中的过程以打包在 PL/SQL 中