过程(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.
【讨论】:
谢谢,刚刚做到了。不过没有变化,错误消息保持不变。 如果您从 SQLplusSELECT "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 无效游标”的主要内容,如果未能解决你的问题,请参考以下文章