2011-12-14 8 views
0

なぜこのエラーが発生していますか?警告:コンパイルエラーで作成された手順ですか?

CREATE OR REPLACE trigger customerLineCount 
BEFORE insert on cust_line 
for each row 
when(new.cust_id > 0) 
DECLARE 
    lineCount number; 
BEGIN 
    select count (*) into lineCount 
    from (cust_line inner join customer 
    on cust_line.cust_id = customer.cust_id) 
    where (customer.cust_id = :new.cust_id) 

    if :new.gender = "m" and lineCount = 3 THEN 
     dbms_output.put_line ('Error! User already has 3 lines'); 
    elseif :new.gender = "f" and lineCount = 1 THEN 
     dbms_output.put_line ('Error! User already has 1 line'); 
    end if; 
END customerLineCount; 
/
+4

コンパイルエラーのメッセージを表示するには 'show errors'を実行してください(またはuser_errorsなどから選択してください) – derobert

答えて

3

体の最初の選択の後にセミコロンがありません。

5

1)PL/SQLの文字列は、二重引用符ではなく、一重引用符で区切ります。あなたはgenderが何であるかを確認したいのであれば、あなたはあなたのSELECT文が最後にセミコロンが欠落している)

if :new.gender = 'm' and lineCount = 3 THEN 
    dbms_output.put_line ('Error! User already has 3 lines'); 
elseif :new.gender = 'f' and lineCount = 1 THEN 
    dbms_output.put_line ('Error! User already has 1 line'); 
end if; 

2のようなものが必要だろう。

3)しかし、コンパイルエラーを解決すると、ほとんど確実にランタイムエラーが発生します。一般に、表の行レベル・トリガーは同じ表を照会できません。したがって、cust_lineの行レベルのトリガーはcust_lineテーブルを照会できません。 PL/SQLコレクションを含むパッケージを作成し、次に複数のトリガーを作成することによって、潜在的に回避できます。 before文トリガはコレクションを初期化し、行レベルのトリガは新しく挿入された行のキーでコレクションを埋めます。そして、afterステートメントトリガーは、コレクションを繰り返し、テーブルを照会して、必要なビジネスロジックを適用します。しかし、これは実際にはめったに必要ではない非常に複雑なアプローチです。一般的には、トリガーではなく制約を使用するか、挿入を行うストアード・プロシージャーでビジネス・ルールを適用する方がはるかに優れています。

+0

+1トリガーの使用に関する制約を推奨します –