Oracle 如何在dbms_sql.open_游标上解决ORA-29471?
我正在使用Oracle 11.2.0.1.0,并试图让dbms_sql包正常工作。 但是,我不断得到ORA-29471错误,如下所示:Oracle 如何在dbms_sql.open_游标上解决ORA-29471?,oracle,plsql,dynamic-sql,Oracle,Plsql,Dynamic Sql,我正在使用Oracle 11.2.0.1.0,并试图让dbms_sql包正常工作。 但是,我不断得到ORA-29471错误,如下所示: DECLARE c INTEGER; BEGIN c := dbms_sql.open_cursor(); END; ORA-29471: DBMS_SQL access denied ORA-06512: at "SYS.DBMS_SQL", line 1017 ORA-06512: at line 4 甲骨文对此有如下说法: 绑定和执行时进行检查
DECLARE
c INTEGER;
BEGIN
c := dbms_sql.open_cursor();
END;
ORA-29471: DBMS_SQL access denied
ORA-06512: at "SYS.DBMS_SQL", line 1017
ORA-06512: at line 4
甲骨文对此有如下说法:
绑定和执行时进行检查。可选地,可以使用支票
为每个DBMS_SQL子程序调用执行。支票是:
- 当前_用户在调用子程序时与调用最近的解析时相同
- 调用子程序时启用的角色必须是调用最新解析时启用的角色的超集
dbms\u sql.open\u cursor
处得到了错误,这是安全级别的第一个定义
支持网站还提出了一个解决方案,包括设置:
alter system set "_dbms_sql_security_level" = 384 scope=spfile;
我还没试过。我更愿意将其视为最后手段,因为它涉及到禁用安全层,并且是不受支持的oracle功能。这几乎不是生产使用的理想环境。而且,它根本没有真正解决问题,只是隐藏了它
如何解决此错误?您的代码引发ORA-29471
的唯一原因(此时无法看到另一个原因)是您已通过提供无效的游标ID使dbms\u sql
在会话中不可操作:
/* dbsm_sql detects invalid cursor ID in this session */
SQL> declare
2 c_1 number := 5; -- invalid cursor ID. There is no cursor
3 l_res boolean; -- opened with ID = 5
4 begin
5 l_res := dbms_sql.is_open(c_1);
6 end;
7 /
declare
*
ERROR at line 1:
ORA-29471: DBMS_SQL access denied
ORA-06512: at "SYS.DBMS_SQL", line 1104
ORA-06512: at line 5
/* An attempt to execute this simple anonymous PL/SQL block after
an invalid cursor ID has already been detected by the dbms_sql
in the current session will lead to ORA-29471 error
*/
SQL> declare
2 c_2 number;
3 begin
4 c_2 := dbms_sql.open_cursor();
5 end;
6 /
declare
*
ERROR at line 1:
ORA-29471: DBMS_SQL access denied
ORA-06512: at "SYS.DBMS_SQL", line 1084
ORA-06512: at line 4
尝试在新建立的会话中执行该代码解决方案可以是查看
v$session
视图
如果光标存在于列表中,则表示您仍可以使用它。然后从它的sql\u id
中识别它,您可以进行检查。您可以在此处生成列表:
select sql_id, sql_text, count(*) as "OPEN CURSORS", user_name
from v$open_cursor
where user_name <>'SYS'
group by sql_text, user_name
order by count(*) desc;
选择sql\u id、sql\u文本、计数(*)作为“打开的游标”、用户名
从v$open\u游标
其中用户名为“SYS”
按sql\u文本、用户名分组
按计数排序(*)说明;
更多。该死的。我正要说同样的话,但你抢先说了+1我刚刚以与您相同的方式重新编写了错误,正要将SQL*Plus输出粘贴到我的答案中,这时我看到了您的答案。如果我对此感到如此不安,我就不会高估你的职位你说得对。建立新的会议解决了这个问题。我真不敢相信我花了一个多小时才发现这一点。谢谢@Nicholas Krasnov我们如何确定DBMS_SQL的特定会话无效?@NickKrasnov哇,我不敢相信重新打开一个新会话就能解决这个问题。多亏了你的回答,我才节省了几个小时。我可以请你强调一下建立新连接的部分吗?一些非鹰眼用户可能没有意识到这一点。谢谢:)一个解决方案可能是查看v$Session视图。更多。