ストアドプロシージャ内で即時に実行すると、不十分な特権エラーが発生し続けます
-
13-09-2019 - |
質問
ストアドプロシージャの定義は次のとおりです。
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');
何らかの理由で、私は即時コマンドを実行するために不十分な特権エラーを取得し続けます。私はオンラインで見ましたが、特権エラーが不十分な場合、通常、Oracleユーザーアカウントが合格したクエリで使用されるコマンドの特権を持たないことを意味します。この場合はドロップされます。しかし、私はドロップ特権を持っています。私は本当に混乱しており、私に役立つ解決策を見つけることができないようです。
よろしくお願いします。
解決:
以下で述べたように、Oracle Securityモデルは、手順のどこかでどのような特権を使用するかを明示的に知る必要があるという点で奇妙です。 Oracleに、作成または交換ステートメントでAuthIDキーワードを使用することを知らせる方法。手順の作成者と同じレベルの特権が必要な場合は、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;
皆さんに返信していただきありがとうございます。これは、解決策に到達するための非常に迷惑な問題でした。
解決
Oracleのセキュリティモデルは、即時(PL/SQLブロックまたは手順のコンテキスト内で)を使用して動的SQLを実行する場合、ユーザーはロールメンバーシップを介して付与されるオブジェクトまたはコマンドに特権を持たないようなものです。ユーザーは「DBA」の役割または同様のものを持っている可能性があります。このユーザーに「ドロップテーブル」権限を明示的に付与する必要があります。別のスキーマのテーブル(SYSやシステムなど)のテーブルから選択しようとしている場合も同じことが当てはまります。このテーブルに明示的な選択特権をこのユーザーに付与する必要があります。
他のヒント
この例を使用する必要があります 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;
/
要件の手順定義の本文で「authid current_user」を使用できます。
または、ユーザーに付与することもできます DROP_ANY_TABLE
必要に応じて特権があり、手順は変更を必要とせずに実行されます。危険かもしれませんが、あなたが何をしているのかに依存します:)