1

概念的には単純ですが、実際にはもっと複雑に見えることをしたいと思います。

基本的に、データベース内の2人のユーザーに対して新しいテーブルが作成されるたびに、ロールにselect権限を付与したいと思います。基本的にこれ:

grant select on TABLENAME to READROLE;

これまでのところ、私のトリガーは次のようになっています。

トリガーの作成または置換osmm_grant_on_creation

OSMM.SCHEMAで作成した後

始める

    //grant goes here

終わり

問題は、新しく作成されたテーブルの名前を取得し、トリガーを介してそれを付与に参照することによって、2つを結合する方法を理解できないことです。助言がありますか?ありがとう。

4

2 に答える 2

13

思っているよりも複雑かもしれません。ステートメントはDDLです。GRANTこれは、暗黙のコミットを発行することを意味します。つまり、トリガーに直接入れることはできません。トリガーは、トリガートランザクションがコミットされた後、別のセッションで実行されたジョブを送信する必要があります。これにより、実際に許可が行われます。つまり、最新のパッケージも暗黙的にコミットするため、古いDBMS_JOBパッケージを使用してジョブをスケジュールする必要があります。DBMS_SCHEDULER

そもそもOracleでその場でテーブルを作成するべきではないので、この種の付与の適切な場所は、最初にテーブルを作成するために実行するビルドスクリプトです。2つの異なる環境でまったく同じスクリプトを実行すると、トリガーの違いにより2つの異なる結果が生成される可能性があるため、許可などをトリガーに依存すると、ビルドを適切に実行することがより困難になる傾向があります。

ただし、この道を進むと決心した場合は、おそらく次のようなものが必要になります。

特権を付与する手順

CREATE OR REPLACE PROCEDURE grant_select_to_readrole( p_table_name IN VARCHAR2 )
AS
BEGIN
  EXECUTE IMMEDIATE 'grant select on ' || p_table_name || ' to readrole';
END;

そして、このプロシージャを呼び出すジョブを送信するトリガー

CREATE OR REPLACE TRIGGER osmm_grant_on_creation
  AFTER CREATE ON OSMM.SCHEMA
AS
  l_jobno PLS_INTEGER;
BEGIN
  dbms_job.submit( l_jobno,
                   'BEGIN grant_select_to_readrole( ''' || ora_dict_obj_name || ''' ); END;',
                   sysdate + interval '10' second );
END;

スキーマレベルのトリガー自体でDDLを発行しようとすると、エラーが発生します

SQL> ed
Wrote file afiedt.buf

  1  create or replace trigger after_create_on_scott
  2    after create on schema
  3  declare
  4  begin
  5    execute immediate 'grant select on scott.emp to hr';
  6* end;
SQL> /

Trigger created.

SQL> create table foo( col1 number );
create table foo( col1 number )
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-30511: invalid DDL operation in system triggers
ORA-06512: at line 3
于 2012-02-13T15:38:43.650 に答える
-1

あなたはおそらく次のようなことをする必要があります:

CREATE OR REPLACE TRIGGER osmm_grant_on_creation

AFTER CREATE ON OSMM.SCHEMA
DECLARE
new_obj_name varchar2(30);
BEGIN
SELECT ora_dict_obj_name
INTO new_obj_name
FROM dual
WHERE ora_dict_obj_type = 'TABLE';

execute immediate 'grant select on ' || new_obj_name || ' to READROLE';
END

でも動作するか確認できません

于 2012-02-13T15:37:57.670 に答える