PL/SQL 中程序包或者函数处于无效状态是啥原因造成的?请教!!

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PL/SQL 中程序包或者函数处于无效状态是啥原因造成的?请教!!相关的知识,希望对你有一定的参考价值。

我用的是scott用户登录的!

很多表视图的变动都会造成过程状态失效。所以每次修改表结构什么的,都要主动的去检查相关的过程函数是否失效。
至于你截图里的失效 怎么会在那里写call ?
参考技术A 举个具体的例子。

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

【中文标题】过程(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 中程序包或者函数处于无效状态是啥原因造成的?请教!!的主要内容,如果未能解决你的问题,请参考以下文章

oracle 10g R2数据库,用pl/sql developer 删除数据时,执行DELETE FROM TABLE1后就一直停在执行的状态,

Mysql、SQL server有没有PL/SQL?或者是类似PL/SQL的东西?PL/SQL是否存储过程?

PL/SQL 编译失败,没有错误消息

请教oracle pl/sql中延时语句的写法

PL/SQL程序在哪里执行,困惑,说的详细些……谢谢

oracle中,用pl/sql创建触发器报触发器无效且未通过重新验证