Как решить ORA-29471 на СУБД 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

оракул docs скажите следующее об этом:

проверки производятся при привязке и выполнении. Выборочно, проверки могут быть выполняется для каждого вызова подпрограммы DBMS_SQL. Чек:

  • current_user такой же при вызове подпрограммы, как это было при вызове самого последнего разбора.
  • разрешенные роли при вызове подпрограммы должны быть надмножеством разрешенных ролей при вызове последнего синтаксического анализа.

В соответствии с использованием подпрограмм прав определителя роли не применять. Если проверка завершается неудачно и возникает ошибка ORA-29470.

насколько я могу судить, оба условия не распространяются на мой код, потому что код не схемы.

Оракул поддержка (требуется логин) веб-сайт предлагает мне явно добавить параметр security_level в dbms_sql.открытый курсор. Добавление любого из значений (0/1/2) не решает проблему.

загадка для меня в том, что я получаю ошибку в dbms_sql.open_cursor, где сначала определяется уровень безопасности.

сайт поддержки также предлагает решение, которое включает в себя:

alter system set "_dbms_sql_security_level" = 384 scope=spfile;

Я еще не пробовал. Я предпочитаю думать об этом как последнее средство, поскольку оно включает в себя отключение уровня безопасности и является неподдерживаемой функцией oracle. Едва ли идеальные условия для использования в производстве. Кроме того, это на самом деле не решает проблему вообще, просто скрывает ее.

как я могу решить эту ошибку?

2 ответов


единственная причина(не вижу в этот момент), почему ваш код вызывает ORA-29471 вы уже сделали dbms_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_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;

больше здесь.