2016-05-23 21 views
0

私はこのトリガーを回避しています。スクリプトを実行すると、前のエラー・メッセージが表示されます。私はそれが正しくコンパイルされない理由を把握することができない、すべてのPL/SQLのトリガチュートリアルは、私のトリガが持っている構造を持っているようだ。コードは以下の通りです:新しいアーティストは、すでにそのスーパータイプ(演奏者)に存在する場合、それはそれはアーティストに両方を挿入していない場合、それはエラーを与える存在しない場合ORA-24344:コンパイル・エラーで成功 - トリガーAPEX

create 
    or replace trigger new_artist before insert 
     on 
     Artist referencing new as nvartist declare counter number; 

begin select 
    count(*) into 
     counter 
    from 
     Performer 
    where 
     Stage_name = nvartist.Stage_name; 

if counter > 0 then signal sqlstate '45000'; 
else insert 
    into 
     Artist 
    values(
     nvartist.Stage_name, 
     nvartist.Name 
    ); 

insert 
    into 
     Performer 
    values(nvartist.Stage_name); 
end if; 
end; 

それはStage_name VARCHAR2、名前(、チェックvarchar2)とパフォーマー(Stage_name)。 Performerの別のサブタイプ(およびArtistへの兄弟)はBand(Stage_name)で、Artistとの関係もあります。なぜコンパイラはこのトリガのために私に怒鳴りますか?あなたは(私は少しあなたのテーブルの名前を変更)このバリアントを試してみたいことがあり、事前

+0

同じ基本テーブルにデータを挿入しようとすると、トリガエラーの突然変異が原因で実行時にエラーが発生する –

+0

私はそれについて読んで、挿入/更新された行が混乱するとトリガが失敗することを理解しましたトリガー内でその行を直接的または間接的に削除した場合、私はそれが当てはまるとは思わない。私の目的はArtistに挿入する前にPerformerにStage_nameがすでに存在するかどうかをチェックすることです。存在していれば(それは彼らの関係であるため、ISA Artist/Band)パフォーマーはエラーを出しますが、存在しなければアーティストとパフォーマーの両方に挿入します。私はこれがそれを達成すると思った。 – Punk

+0

OracleにはSIGNALコマンドはありません。これはMySqlです。このトリガーはコンパイルされません。シグナルの代わりにraise_application_errorを使用します。あなたは同じテーブルに挿入することはできませんし、必要はありません。 'アーティストに挿入'コマンドを削除します。これは自動的に行われます。 – Mottor

答えて

0

感謝。 サンプルデータを持つテーブルの作成:

CREATE table test_artist(
    stage_name varchar2(100) 
, name varchar2(100) 
); 

create table test_performer(
    stage_name varchar2(100) 
); 

/*inserting test performer on which trigger will rise an error*/ 
insert into test_performer 
select 'performer_1' from dual; 

は、トリガーの作成:

create or replace trigger new_artist 
    before insert 
    on TEST_ARTIST 
    referencing new as nvartist 
    for each row 

declare 
    counter number; 
begin 
    select count(*) 
    into counter 
    from test_performer 
    where Stage_name = :nvartist.Stage_name; 

    if counter > 0 then 
     --signal sqlstate '45000' ; 
     raise_application_error(-20001, 'No insertion with existing Performer'); 
    else 
     /*you cant update the same table, in other case you'll get 
     ora-04091 table mutating error.  
     But nevertheless this values will be inserted by sql triggered this trigger.*/ 
     --insert into test_artist values(:nvartist.Stage_name, :nvartist.Name);  
     insert into test_performer values(:nvartist.Stage_name); 
    end if; 
end new_artist; 

このインサートは、動作することの後に、 'test_performer' テーブルには 'performer_2' ではありません原因:

insert into test_artist 
select 'performer_2', 'name_2' from dual; 

これは失敗します:

insert into test_artist 
select 'performer_1', 'name_1' from dual; 
+0

深い答えをありがとう。私はテーブルの変異について疑念を持っていましたが、私はアーティストへの挿入がまだ起こるかどうかは確かではありませんでした。ここでは各行に重複していないのですか?カウンタはカウントクエリで満たされるので、まだ各行をチェックする必要がありますか? – Punk

+0

こんにちは、@パンク! "FOR EACH ROWオプションは、トリガが行トリガであるかステートメントトリガであるかを決定します。 1つのステートメントにつき多くの行を 'Artist'テーブルに挿入することができますので、特定の行ごとに演奏者の存在チェックを行う必要があります。もう1つは、テーブルレベルのトリガーでは使用できない新しい参照または古い参照です。 –

関連する問題