4

トリガーが存在するスキーマの外部にある別のテーブルを照会するテーブルトリガーを作成しようとしています。これは可能ですか?スキーマ内のテーブルのクエリに問題はないようですが、次のようになります。

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特権」についてはよくわかりません。

4

3 に答える 3

5

あなたが経験しているのは、Oracleのセキュリティモデルの機能です。スキーマを使用することの全体的なポイントは、データへのアクセスを制御することです。私のスキーマのテーブルは私のものであり、私があなたにそれらの特権を与えるまで、あなたはそれらを見ることさえできません。

構文は非常に単純です。所有者スキーマの問題

grant select, insert on my_table to you
/

または、GRANT ANY特権を持つアカウント(DBAなど)は、任意のユーザーのオブジェクトに対する特権を渡すことができます。

grant select, insert on apc.my_table to you
/

被付与者は、ユーザーまたはロールのいずれかです。ただし、ユーザーに直接付与された特権を使用してのみ、プログラムユニット(ストアドプロシージャ、ビュー、トリガー)を構築できることに注意してください。

したがって、他のスキーマ所有者に必要な特権を付与してもらうと、トリガーを作成できるようになります。

編集

別のスキーマでオブジェクトを参照する場合は、オブジェクトをスキーマ名で修飾する必要があります...。

insert into apc.whatever_table  values ...

または、その同義語を作成する必要があります

create synonym whatever for apc.whatever_table;
于 2010-04-16T23:06:37.460 に答える
2

誰かが明白なものを追加する必要があると思います-他のスキーマのテーブルはスキーマ名で修飾する必要があります。そうでない場合は、プライベート/パブリックの同義語が必要です。元々の問題は単に名前解決の問題だったのだろうか。そうでない場合、APCの答えはOracleセキュリティモデルの良い説明です。

于 2010-04-17T00:22:34.073 に答える
0

関連するすべてのテーブルとスキーマに対してこれを実行する必要があります。

grant select on OTHER_SCHEMA_%.table_name to MAIN_SCHEMA;
于 2010-04-20T12:55:45.490 に答える