2016-06-23 6 views
0

私は下記のトリガーを作成しましたが、私が言及したテーブルへの新しい挿入/更新をしていた後、それが解雇されていません。テーブルに挿入や更新が行われたときに起動するトリガを作成する方法は?

CREATE OR REPLACE TRIGGER ref_upd_user_phi_details 
AFTER 
INSERT OR UPDATE --of emp_email_address, ssn_nb 
ON ref_adp_employees 
REFERENCING OLD AS OLD NEW AS NEW 
FOR EACH ROW 
BEGIN 
     UPDATE ref_adp_employees 
     SET emp_email_address = 'QA_' ||emp_email_address, 
      ssn_nb = nvl2(ssn_nb, NULL, '123-45-6789') 
     WHERE upper(emp_email_address) NOT LIKE 'QA_%' 
     AND upper(emp_email_address) LIKE '%@KEENAN.COM'; 
exception 
     WHEN others 
      THEN 
       NULL; 
END; 

誰かが私が行方不明です何を私に提案してくださいことはできますか?

+1

なぜWHEN OTHERS例外をキャッチして何もしません。当面はあなたの例外セクションを完全に削除し、トリガーを再コンパイルしてください。挿入/更新を行い、エラーが発生していないか確認してください。 –

+0

また、更新ステートメントは静的な更新プログラムのようです。トリガーで新しく作成または更新されたレコードの値を使用していません。このトリガーで達成しようとしていることは何ですか? –

+0

@phonetic_man:例外セクションを削除した後に、私があなたに求めた最初の条件をチェックしましょう。新しいレコードが挿入されたり、既存のレコードが更新されたりすると、このトリガを起動します。 –

答えて

0

Googleについて聞いたことがありますか?トリガーにはたくさんの回答とサンプルがありますが、今回はいくつか見ています。

1)トリガーを挿入または更新する前に変更してください。別のテーブルに変更を加える場合や、後続のプロセスをテーブルで実行する場合は、AFTERを使用します。

2)変更または追加されている個々のフィールドにコメントを取り出します。それは良いAFAIKだった。

3)トリガーの体には、挿入時と更新時を使用します。または、単に表を更新する場合は、DDLをBEFORE UPDATEに変更します。

4)アップデートでは、set:new.emp_email_address = 'QA_' ||で参照してください。 :old.emp_email_address ...などと続きます。それは、古いものと新しいものとの古いものが重要になる場所です。トリガーは、以下のクエリを焼成することにより、有効であるかどうか

+0

は、私が試した第4ポイント –

+0

にしようとします。 (old.ssn_nb、NULL、 '123-45-6789') WHERE upper(:old.emp_email_address) 'QA_%'と一致しない AND(:old.emp_email_address)LIKE '%@KEENAN.COM'; --exception - その他の場合 - THEN - NULL; END; –

0

親切@phonetic_manが指摘したように、トリガーが更新

CREATE OR REPLACE TRIGGER ref_upd_user_phi_details 
Before 
INSERT OR UPDATE 
+0

クエリを共有してくれてありがとう。また、あなたが上記のトリガーを作成する際に何が欠けているのかを示唆できる場合。 –

1

前..更新後 試みを発射ます。..

SELECT * 
FROM ALL_OBJECTS 
WHERE OBJECT_NAME = trigger_name 
AND OBJECT_TYPE = 'TRIGGER' 
AND STATUS <> 'VALID' 

をチェックあなたは、when othersを捕まえて何もしないで、どんなエラーも隠しています。例外ブロックがないと、トリガーと同じ表を参照しているため、変換表エラー(ORA-04091)が発生していることがわかります。

for each row部分を取り出して文レベルのトリガーにすると、その問題は回避されますが、今度は無限ループ(ORA-00036)が発生します.-表を内部から更新しようとするとそのトリガは、それ自身を更新して同じトリガを再び発動させます。同じテーブルを再度更新しようとすると、トリガーがもう一度起動します。 Oracleがプロセスに気付いてプロセスを終了するまで、

挿入前の行レベルのトリガを使用して、行の新しい値が、実行しようとしているパターンに一致することを確認するのが理にかかります。多分何かのように:

CREATE OR REPLACE TRIGGER ref_upd_user_phi_details 
BEFORE INSERT OR UPDATE --of emp_email_address, ssn_nb 
ON ref_adp_employees 
REFERENCING OLD AS OLD NEW AS NEW 
FOR EACH ROW 
BEGIN 
    IF upper(:NEW.emp_email_address) NOT LIKE 'QA_%' 
     AND upper(:NEW.emp_email_address) LIKE '%@KEENAN.COM' 
    THEN 
     :NEW.emp_email_address := 'QA_' || :NEW.emp_email_address; 
     :NEW.ssn_nb := CASE WHEN :NEW.ssn_nb IS NULL THEN '123-45-6789' END; 
    END IF; 
END; 
/

そして、それが何を参照するには:

insert into ref_adp_employees (emp_id, emp_email_address, ssn_nb) values (1, 'TEST_1', '123-45-6789'); 
insert into ref_adp_employees (emp_id, emp_email_address, ssn_nb) values (2, '[email protected]', '123-45-9876'); 
insert into ref_adp_employees (emp_id, emp_email_address, ssn_nb) values (3, 'QA_TEST_1', null); 

select emp_id, emp_email_address, ssn_nb from ref_adp_employees; 

    EMP_ID EMP_EMAIL_ADDRESS    SSN_NB  
---------- ------------------------------ ----------- 
     1 TEST_1       123-45-6789 
     2 [email protected]      
     3 QA_TEST_1         

わからないあなたが本当に固定値にNULLをヌルとセットのSSNを交換し、有効にすることを意図している場合。私はそれは次のようになり、その場合には、あなたが本当に固定文字列で設定値を置き換えるためにしようとしている疑いがあると一人でヌルを残し:

 :NEW.ssn_nb := CASE WHEN :NEW.ssn_nb IS NOT NULL THEN '123-45-6789' END; 

それは関係なく、行われていますので、あなたはまた、IFブロックの外側それを移動したい場合があります電子メールアドレス。元のコードがやろうとしていたことを再現しましたが、それは正しいとは限りません。

これらの変更に合わせて変更する既存のデータがある場合は、テーブル全体を1回限りの更新で実行します。トリガー内でそのデータを更新しようとしないでください。

+0

これは現在正常に動作している:、emp_email_addressのTRIGGERのref_upd_user_phi_detailsをCREATE OR REPLACE BEFORE INSERT OR UPDATE上位場合は、各ROW FOR NEW AS REFERENCING OLD AS OLD NEWは をBEGIN ref_adp_employees ON ssn_nb (:NEW.emp_email_address)は、NOT LIKE 'QA_%' AND(:NEW.emp_email_address)LIKE '%@KEENAN.COM' THEN :NEW.emp_email_address:= 'QA_' || :NEW.emp_email_address;:NEW.ssn_nb:=事例:NEW.ssn_nbはNULLではありません。「123-45-6789」終了; END IF;:NEW.ssn_nb:=事例:NEW.ssn_nbはNULLではありません。「123-45-6789」終了; END; –

+0

@Oracle_UNIX_aspirant - それは他の人には役に立たないし、コードを読んで(またはその関連性を)コメントとして読みにくいです。 'ssn_nb'の変更をもう一度入れて、すべての更新/挿入に適用するようです。あなたは 'IF'ブロックの中にそれを必要としません。 –

関連する問題