Немедленное выполнение в хранимой процедуре приводит к недостаточной ошибке привилегий - PullRequest
35 голосов
/ 15 июня 2009

Вот определение хранимой процедуры:

CREATE OR REPLACE PROCEDURE usp_dropTable(schema VARCHAR, tblToDrop VARCHAR) IS
BEGIN
  DECLARE v_cnt NUMBER;
  BEGIN
    SELECT COUNT(*) 
      INTO v_cnt 
      FROM all_tables 
     WHERE owner = schema
       AND table_name = tblToDrop;

     IF v_cnt > 0 THEN 
        EXECUTE IMMEDIATE('DROP TABLE someschema.some_table PURGE');
     END IF;
   END;
END;

Вот звонок:

CALL usp_dropTable('SOMESCHEMA', 'SOME_TABLE');

По какой-то причине я получаю сообщение об ошибке недостаточных привилегий для команды EXECUTE IMMEDIATE. Я посмотрел онлайн и обнаружил, что ошибка недостаточных привилегий обычно означает, что учетная запись пользователя oracle не имеет привилегий для команды, используемой в запросе, который проходит, в данном случае это DROP. Однако у меня есть привилегии. Я действительно смущен и не могу найти решение, которое работает для меня.

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

РЕШЕНИЕ:

Как Стив упомянул ниже, модель безопасности Oracle странна тем, что ей необходимо точно знать где-то в процедуре, какие привилегии использовать. Чтобы дать Oracle знать об этом, используйте ключевое слово AUTHID в операторе CREATE OR REPLACE. Если вы хотите иметь тот же уровень привилегий, что и создатель процедуры, используйте AUTHID DEFINER. Если вы хотите, чтобы Oracle использовал привилегии пользователя, который в данный момент выполняет хранимую процедуру, вы должны использовать AUTHID CURRENT_USER. Объявление процедуры выглядит следующим образом:

CREATE OR REPLACE PROCEDURE usp_dropTable(schema VARCHAR, tblToDrop VARCHAR) 
AUTHID CURRENT_USER IS
BEGIN
  DECLARE v_cnt NUMBER;
  BEGIN
    SELECT COUNT(*) 
      INTO v_cnt 
      FROM all_tables 
     WHERE owner = schema
       AND table_name = tblToDrop;

     IF v_cnt > 0 THEN 
        EXECUTE IMMEDIATE('DROP TABLE someschema.some_table PURGE');
     END IF;
   END;
END;

Спасибо всем за отклик. Это была определенно очень неприятная проблема, чтобы найти решение.

Ответы [ 4 ]

17 голосов
/ 15 июня 2009

Модель безопасности Oracle такова, что при выполнении динамического SQL с использованием Execute Immediate (в контексте блока или процедуры PL / SQL) пользователь не имеет привилегий для объектов или команд, которые предоставляются через членство в роли. Ваш пользователь, скорее всего, имеет роль "DBA" или что-то подобное. Вы должны явно предоставить разрешения «удалить таблицу» этому пользователю. То же самое применимо, если вы пытаетесь выбрать из таблиц в другой схеме (например, sys или system) - вам необходимо предоставить явные привилегии SELECT для этой таблицы этому пользователю.

4 голосов
/ 18 мая 2017

Вы должны использовать этот пример с AUTHID CURRENT_USER :

CREATE OR REPLACE PROCEDURE Create_sequence_for_tab (VAR_TAB_NAME IN VARCHAR2)
   AUTHID CURRENT_USER
IS
   SEQ_NAME       VARCHAR2 (100);
   FINAL_QUERY    VARCHAR2 (100);
   COUNT_NUMBER   NUMBER := 0;
   cur_id         NUMBER;
BEGIN
   SEQ_NAME := 'SEQ_' || VAR_TAB_NAME;

   SELECT COUNT (*)
     INTO COUNT_NUMBER
     FROM USER_SEQUENCES
    WHERE SEQUENCE_NAME = SEQ_NAME;

   DBMS_OUTPUT.PUT_LINE (SEQ_NAME || '>' || COUNT_NUMBER);

   IF COUNT_NUMBER = 0
   THEN
      --DBMS_OUTPUT.PUT_LINE('DROP SEQUENCE ' || SEQ_NAME);
      -- EXECUTE IMMEDIATE 'DROP SEQUENCE ' || SEQ_NAME;
      -- ELSE
      SELECT 'CREATE SEQUENCE COMPTABILITE.' || SEQ_NAME || ' START WITH ' || ROUND (DBMS_RANDOM.VALUE (100000000000, 999999999999), 0) || ' INCREMENT BY 1'
        INTO FINAL_QUERY
        FROM DUAL;

      DBMS_OUTPUT.PUT_LINE (FINAL_QUERY);
      cur_id := DBMS_SQL.OPEN_CURSOR;
      DBMS_SQL.parse (cur_id, FINAL_QUERY, DBMS_SQL.v7);
      DBMS_SQL.CLOSE_CURSOR (cur_id);
   -- EXECUTE IMMEDIATE FINAL_QUERY;

   END IF;

   COMMIT;
END;
/
3 голосов
/ 21 августа 2016

вы можете использовать «AUTHID CURRENT_USER» в теле определения вашей процедуры для ваших требований.

0 голосов
/ 04 июня 2011

В качестве альтернативы вы можете предоставить пользователю DROP_ANY_TABLE привилегию, если это необходимо, и процедура будет работать как есть, без каких-либо изменений. Может быть, опасно, но зависит от того, что вы делаете:)

...