PL/SQLの形式でDDLをネイティブに実行することはできません。トリガーを含む。そのためには、動的SQLを使用する必要があります。
トリガーには追加のしわがあります。トリガーはトランザクションの一部として起動され、本体内でコミットを発行することを禁止する制限があります。 Oracleでは、DDLコマンドは2つのコミットを発行します。1つはDDLステートメントの実行前と1つは実行後です。したがって、トリガーでDDLを実行するには、autonomous_transaction pragma
を使用する必要があります。 、これは、DDLが別個のネストされたトランザクションで実行されることを意味します。
create or replace TRIGGER TestTrigger
BEFORE INSERT ON TestTable
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
declare
pragma autonomous_transaction;
BEGIN
execute immediate 'create role '|| :New.RoleName;
END;
自律トランザクションは、私たちが自分のアプリケーションを悪用したり妨害したりしやすい構造の1つです。あなたのシナリオでは、TestTable
へのINSERTT中に、CREATEROLEがトランザクションバブルで成功する可能性があります。 失敗します。これが「自律取引」の意味です。したがって、「[あなたの]テーブルとOracleロール1の間の一貫性」はまだ保証されていません。
より良い解決策は、DMLをだまして想定外のことを実行させるのではなく、両方のステートメントを手続き型呼び出しにラップすることです。
create or replace procedure create_role
( p_role_name in user_roles.role%type
, p_desc in testtable.description%type )
is
pragma autonomous_transaction;
begin
insert into testtable
( id, creationdate, rolename, description)
values
( some_seq.nextval, sysdate, p_role_name, p_desc );
execute immediate 'create role '|| p_role_name;
end;