トリガーが存在するスキーマの外部にある別のテーブルを照会するテーブルトリガーを作成しようとしています。これは可能ですか?スキーマ内のテーブルのクエリに問題はないようですが、次のようになります。
Error: ORA-00942: table or view does not exist
スキーマ外のテーブルをクエリしようとしたとき。
編集
初めてご利用いただけなかったことをお詫び申し上げます。この質問はもっと単純だという印象を受けました。
別のスキーマにあるテーブルにある場合とない場合があるデータの存在に基づいて、新しく挿入された行の一部のフィールドを変更するトリガーをテーブルに作成しようとしています。
トリガーの作成に使用しているユーザーアカウントには、クエリを個別に実行するためのアクセス許可があります。実際、実行しようとしているクエリをトリガーに出力させて、それ自体で正常に実行することができました。
また、EXECUTEIMMEDIATEステートメントを使用してクエリを動的に構築していることにも注意してください。次に例を示します。
CREATE OR REPLACE TRIGGER MAIN_SCHEMA.EVENTS
BEFORE INSERT
ON MAIN_SCHEMA.EVENTS REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
DECLARE
rtn_count NUMBER := 0;
table_name VARCHAR2(17) := :NEW.SOME_FIELD;
key_field VARCHAR2(20) := :NEW.ANOTHER_FIELD;
BEGIN
CASE
WHEN (key_field = 'condition_a') THEN
EXECUTE IMMEDIATE 'select count(*) from OTHER_SCHEMA_A.'||table_name||' where KEY_FIELD='''||key_field||'''' INTO rtn_count;
WHEN (key_field = 'condition_b') THEN
EXECUTE IMMEDIATE 'select count(*) from OTHER_SCHEMA_B.'||table_name||' where KEY_FIELD='''||key_field||'''' INTO rtn_count;
WHEN (key_field = 'condition_c') THEN
EXECUTE IMMEDIATE 'select count(*) from OTHER_SCHEMA_C.'||table_name||' where KEY_FIELD='''||key_field||'''' INTO rtn_count;
END CASE;
IF (rtn_count > 0) THEN
-- change some fields that are to be inserted
END IF;
END;
トリガーシームは、前述のエラーでEXECUTEIMMEDIATEで失敗します。
編集
私はさらにいくつかの調査を行い、より明確にすることができます。
このトリガーの作成に使用しているユーザーアカウントは、MAIN_SCHEMAまたはOTHER_SCHEMA_Xのいずれでもありません。私が使用しているアカウント(ME)には、スキーマユーザー自身を介して関連するテーブルへの特権が与えられています。例(USER_TAB_PRIVS):
GRANTOR GRANTEE TABLE_SCHEMA TABLE_NAME PRIVILEGE GRANTABLE HIERARCHY
MAIN_SCHEMA ME MAIN_SCHEMA EVENTS DELETE NO NO
MAIN_SCHEMA ME MAIN_SCHEMA EVENTS INSERT NO NO
MAIN_SCHEMA ME MAIN_SCHEMA EVENTS SELECT NO NO
MAIN_SCHEMA ME MAIN_SCHEMA EVENTS UPDATE NO NO
OTHER_SCHEMA_X ME OTHER_SCHEMA_X TARGET_TBL SELECT NO NO
そして、私は次のシステム権限(USER_SYS_PRIVS)を持っています:
USERNAME PRIVILEGE ADMIN_OPTION
ME ALTER ANY TRIGGER NO
ME CREATE ANY TRIGGER NO
ME UNLIMITED TABLESPACE NO
そして、これは私がOracleのドキュメントで見つけたものです。
別のユーザーのスキーマにトリガーを作成する、またはスキーマのトリガーから別のスキーマのテーブルを参照するには、CREATEANYTRIGGERシステム権限が必要です。この特権を使用すると、トリガーを任意のスキーマで作成し、任意のユーザーのテーブルに関連付けることができます。さらに、トリガーを作成するユーザーは、参照されるプロシージャー、関数、またはパッケージに対するEXECUTE特権も持っている必要があります。
ここで:Oracle Doc
したがって、これは機能するはずですが、ドキュメントで参照されている「EXECUTE特権」についてはよくわかりません。