Может ли dbms_session компилировать не sysdba? - PullRequest
1 голос
/ 26 мая 2020

Я пытаюсь использовать sys.dbms_session.set_context в одной из моих хранимых процедур, но получаю следующую ошибку:

ORA-01031: insufficient privileges

Моя проблема в том, что я не могу использовать его в своей хранимой процедуре, однако ... Я получаю ту же ошибку (Недостаточные привилегии), когда выполняю его подключенным как пользователь, имеющий привилегии выполнения (и привилегии sysdba). Вот код:

PROCEDURE set_my_env (p_attribute IN VARCHAR2,p_value IN VARCHAR2)
  IS
   l_namespace   VARCHAR2 (30) := 'MY_ENV';
   l_attribute   VARCHAR2 (30) := NULL;
   l_value       VARCHAR2 (4000) := NULL;
  BEGIN
   l_attribute := p_attribute;
   l_value := p_value;

    DBMS_OUTPUT.PUT_LINE('NAMESPACE: ' || l_namespace);
    DBMS_OUTPUT.PUT_LINE('Attribute: ' || l_attribute);
    DBMS_OUTPUT.PUT_LINE('value: ' || l_value);

   DBMS_SESSION.set_context (l_namespace, l_attribute, l_value);

   END set_my_env;

Когда я выполняю этот код как пользователь, не являющийся пользователем sysdba (но у него есть права на выполнение), я получаю ошибку недостаточных прав.

Заранее спасибо.

1 Ответ

2 голосов
/ 26 мая 2020

DBMS_SESSION - это встроенный пакет, он установлен вместе с установкой базы данных, действителен и готов к использованию. Зачем вам его компилировать (особенно подключенный как обычный пользователь)?

В любом случае, вернемся к вашему вопросу: почему другие пользователи не могут его скомпилировать? Потому что это принадлежит кому-то другому . SYS. Предоставление привилегии execute означает, что вы можете использовать it, а не компилировать it.

Чтобы иметь возможность компилировать чужие процедуры (пакеты, что угодно), вам необходимо предоставить системную привилегию alter any procedure. Однако это не включает объекты, принадлежащие SYS. Чтобы перекомпилировать их, вам необходимо подключить as sysdba.


Если вы хотите, чтобы он (dbms_session) работал, вот как: подключиться как SYS, предоставить необходимые права пользователю (scott в моем примере):

SQL> show user
USER is "SYS"
SQL> grant create any context, drop any context, alter session, unlimited tablespace to scott;

Grant succeeded.

SQL> grant execute on dbms_session to scott;

Grant succeeded.

SQL>

Теперь подключитесь как scott; это все равно не сработает:

SQL> connect scott/tiger
Connected.
SQL> exec dbms_session.set_context('my_context', 'my_parameter', 'Littlefoot');
BEGIN dbms_session.set_context('my_context', 'my_parameter', 'Littlefoot'); END;

*
ERROR at line 1:
ORA-01031: insufficient privileges
ORA-06512: at "SYS.DBMS_SESSION", line 101
ORA-06512: at line 1

Что вам нужно сделать, так это создать пакет, который вы будете использовать для своего context бизнеса, и создать контекст, который использует этот пакет. Это упрощенная версия, вы бы использовали что-нибудь умнее :

SQL> create or replace package pkg_context as
  2    procedure p_set;
  3  end;
  4  /

Package created.

SQL> create or replace package body pkg_context as
  2    procedure p_set as
  3      begin
  4        dbms_session.set_context('my_context', 'my_parameter', 'Littlefoot');
  5      end;
  6  end;
  7  /

Package body created.

SQL> create context my_context using pkg_context;

Context created.

SQL>

Теперь мы готовы!

SQL> exec pkg_context.p_set;

PL/SQL procedure successfully completed.

SQL> select sys_context('my_context', 'my_parameter') from dual;

SYS_CONTEXT('MY_CONTEXT','MY_PARAMETER')
--------------------------------------------------------------------------------
Littlefoot

SQL>

Верно; теперь все работает как положено.

...