2017-06-15 3 views
1

私は会社のデータベースのトリガを作成していますが、このトリガは名前を変更する(まれに名前を変更する場合など)前のものと違うか、NOT NULLかを指定します。トリガの名前の更新(前と違う)SQL

これは私が書いたコードです。それはコンパイルしますが、私にはエラーが表示されます(ORA-04091:テーブルCOMPANY.EMPLOYEEは突然変異しています。トリガー/ファンクションには が表示されません)。私はそれがFOR EACH ROWによって引き起こされていることに気がつきましたが、それ以外の場合は:new:oldの参照が機能しないため、削除できません。

CREATE OR REPLACE TRIGGER NO_INVALID_NAME 
AFTER UPDATE OF EMPLOYEE_NAME ON EMPLYEE 
FOR EACH ROW 
DECLARE 
    INVALID_NAME EXCEPTION; 
    CORRECT_NAME EXCEPTION; 

BEGIN 
    UPDATE EMPLOYEE 
    SET EMPLOYEE_NAME =:NEW.EMPLOYEE_NAME 
    WHERE EMPLOYEE_NAME =:OLD.EMPLOYEE_NAME; 

    IF :NEW.EMPLOYEE_NAME <> :OLD.EMPLOYEE_NAME AND IS NOT NULL THEN 
    RAISE INVALID_NAME; 
    ELSE 
    RAISE CORRECT_NAME; 
    END IF; 

EXCEPTION 
    WHEN NOME_NON_CORRETTO 
    THEN RAISE_APPLICATION_ERROR(-20009,'Name cannot be updated.'); 
    WHEN CORRECT_NAME 
    THEN DBMS_OUTPUT.PUT_LINE('Updated.'); 
END; 

私は:NEWと:OLDステートメントで何かを台無しにしていると思いますが、どこに見えません。

+0

あなたがこれを確認しましたか? [Oracle Docs](http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/triggers.htm#LNPLS2005) – SlimsGhost

+0

私は多くのドキュメントを参考にしましたが、私のコードのためのトリックを行う必要がありますか? – smartsoap

+0

ここではビジネスルールを理解できません。更新トリガーが独自のテーブルを更新しようとしているのはなぜですか? 'employee_name'はなぜnullになるのですか?名前の変更を防止したい場合は、単に例外:if:new.employee_name <>:old.employee_name'を発生させてください。名前の変更が許可されている場合、トリガーは何ですか? –

答えて

0

2行目に表名にタイプミスがありますので、EMPLOYEEに変更してください。 NEW.EMPLOYEE_NAMEは前にNULL句ではありませんが、それはすべての問題を修正する場合、私は確信しています:

AFTER UPDATE OF EMPLOYEE_NAME ON EMPLOYEE

私が追加しようとするだろう。

IF(:NEW.EMPLOYEE_NAME <> :OLD.EMPLOYEE_NAME AND :NEW.EMPLOYEE_NAME IS NOT NULL) 
+0

はい、申し訳ありませんが、EMPLYEEは間違いでした。 また、NEW.EMPLOYEE_NAME IS NOT NULLはまだ動作していません。(ORA-04091:表COMPANY.EMPLOYEEは突然変異していますが、トリガー/機能には表示されません)エラーが表示されます。 – smartsoap

+0

おそらくそれは正しく動作していない操作の順序ですか? – smartsoap

+0

更新の前にIFブロックを置くことは良い考えです。このようにして、無効な名前は従業員に割り当てられません。 「名前は更新できません」の代わりに例外は「無効な名前」をスローする可能性があります。従業員を更新しませんでした。 –

0

トリガーでは、更新と同じ操作を行います。 "アプリケーション"が更新を行い(コミットなし)、トリガーは同じ更新を行い、次に:new.nameold.nameを検証します。

はこれを試してみてください:

CREATE OR REPLACE TRIGGER NO_INVALID_NAME 
BEFORE UPDATE ON EMPLOYEE 
FOR EACH ROW 
DECLARE 
    INVALID_NAME EXCEPTION; 
    CORRECT_NAME EXCEPTION; 
BEGIN 
    IF :NEW.EMPLOYEE_NAME <> :OLD.EMPLOYEE_NAME AND :NEW.EMPLOYEE_NAME IS NOT NULL THEN 
     RAISE INVALID_NAME; 
    ELSE 
     RAISE CORRECT_NAME; 
    END IF; 
EXCEPTION 
    WHEN NOME_NON_CORRETTO 
     THEN RAISE_APPLICATION_ERROR(-20009,'Name cannot be updated.'); 
    WHEN CORRECT_NAME 
     THEN DBMS_OUTPUT.PUT_LINE('Updated.'); 
END; 
関連する問題