2009-06-15 3 views
32

Вот определение хранимой процедуры:Выполнение Immediate внутри хранимой процедуры продолжает давать Недостаточные priviliges ошибку

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; 

Вот вызов:

По какой-то причине, я получаю недостаточное привилегии для команды 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; 

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

+0

Я столкнулся аналогичные проблемы, но самое смешное, без использования «AUTHID DEFINER» или «AUTHID CURRENT_USER» процедура была выполнения для таблицы падения но не для создания таблицы. Решение AUTHID работает :) Спасибо! – Aniket

+0

Спасибо, это два слова «AUTHID CURRENT_USER» решают мою проблему! Благодаря! – Roman

ответ

15

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

+1

Спасибо за ответ. Я попробовал 'EXECUTE IMMEDIATE ('GRANT drop table ON' || schema_name || '.' || tblToDrop || 'TO ben');' , но я получаю недопустимую ошибку привилегий для этой строки. Я посмотрел онлайн, чтобы назначить привилегию для удаления таблицы, но я не могу найти ничего. Я попробовал все и «drop table», но получаю ту же ошибку. Вы знаете, где я могу найти правильное имя или что я здесь делаю неправильно? Еще раз, спасибо. – tundal45

+1

Не используйте EXECUTE IMMEDIATE для предоставления привилегии.Вам необходимо предоставить привилегию для перетаскивания BEN: GRANT DROP TABLE TO BEN –

+3

Steve, Я только что понял. Оказывается, я могу определить привилегии в процедуре, используя AUTHID. Если мне нужны те же привилегии, что и создатель, я использую AUTHID DEFINER. Если мне нужны привилегии текущего пользователя, я использую AUTHID CURRENT_USER. Вот как выглядит процедура оболочки: CREATE OR REPLACE PROCEDURE some_procedure AUTHID CURRENT_USER IS НАЧАТЬ DECLARE НАЧАТЬ END; END; – tundal45

0

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

+0

За исключением того, что недействительна причина наличия привилегий в первую очередь. Кроме того, «DROP_ANY_TABLE» вряд ли случайно будет предоставлен на производство для любой крупномасштабной корпорации. –

3

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

2

Вы должны использовать этот пример с 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; 
/

 Смежные вопросы

  • Нет связанных вопросов^_^