2017-04-03 8 views
0

deptの最後の従業員がempテーブルから削除されると、deptがdeptテーブルから削除されるトリガーを作成する必要があります。
EMP(EMPNO、ENAME、DEPTNO)
DEPT(DEPTNO、DNAME)PLSQL_triggerに準拠することができません

まず、IはDEPTNO所与DEPT表からDEPTを削除する手順を作成しました。

CREATE OR REPLACE PROCEDURE del_dept              
    (v_dno in number) 
is 
begin  
    delete from DEPT where deptno = v_dno; 
end; 

次に、その部門の最後のempが削除されたときにその部門を削除するトリガーを作成しました。私はdeptno10で3つのempのうちの1つを削除してトリガーをテストしようとしましたが、トリガーが無効で再検証に失敗したというコマンドからエラーメッセージが出ました。

create or replace trigger del_dept 
after delete on EMP 
for each row 
DECLARE 
    emp_count Number; 
    g_dno Number; 
begin 
    SELECT COUNT(:old.ename) INTO emp_count FROM emp group by deptno; 
    FOR i IN 1.. emp_count LOOP 
     IF i = emp_count THEN 
      del_dept(g_dno);  
     end if;   
    END LOOP; 
End; 
+0

**削除がある何 – hmmftg

+0

に行われた直後に、emp表から**削除しないフォームやアプリケーションでそれを実行します。以下を参照してください。これで 'FOR'ループが必要ですか? 'del_dept'を呼び出すと、' g_dno'の値は何ですか? – Nitish

+0

FORループの私の理由は、その部門のすべてのempをチェックすることです。最後のempでない場合は、deptではなくempを削除してください。私はこの状態をチェックするためにトリガーが必要ないと思う。 g_dnoの値はold.deptnoです。 INパラメータとOUTパラメータを混同しました。手続き/関数を呼び出すときには、INパラメータの値を指定する必要があります。ここで、g_dnoはINパラメータです.Hence、呼び出し元のルーチンにolddeptnoという値を指定する必要があります。 – user7770852

答えて

0

エラーtrigger is invalid and failed re-validationは、したがって、あなたがそれをテストすることができませんでしたヨールトリガがコンパイルエラーで作成されたことを指定します。これはあなたのケースでトリガーを書くのは良い考えではありません。私はあなたのコードでいくつかの問題を見ることができます。最初にこれらの問題を解決しましょう。

以下のコードを記述すると、トリガーがコンパイルされ、有効なものになります。

ORA-04091: table EMP is mutating, trigger/function may not see it

ORA-06512: at "DEL_DEPT", line 4 ORA-04088: error during execution of

trigger 'DEL_DEPT'

このエラーを取得するための理由はあなたからselectしようとしているです:あなたはそれを実行しようとするときに、あなたがさらにエラーになりますtrigger is invalid and failed re-validation

CREATE OR REPLACE TRIGGER del_dept 
    AFTER DELETE 
    ON EMP 
    FOR EACH ROW 
DECLARE 
    EMP_CNT NUMBER; 
BEGIN 
    SELECT COUNT (1) 
    INTO emp_cnt 
    FROM emp 
    WHERE deptno = :old.deptno; 

    IF emp_cnt = 0 
    THEN 
     ---del_dept is your procedure to delete records from dept table 
     del_dept (:old.deptno); 
    END IF; 
END; 

エラーを取得しませんがtableあなたはdeletingレコードであり、それはoracleには許可されていません。

ケースの最適な方法は、最後の従業員データがdeptテーブルから削除されるとレコードを削除するプロシージャを作成することです。 、こんにちは、それがトリガーとそれを削除するには良い方法ではありません

CREATE OR REPLACE PROCEDURE del_dept (dept_no NUMBER) 
IS 
    EMP_CNT NUMBER; 
BEGIN 
    SELECT COUNT (1) 
    INTO emp_cnt 
    FROM emp 
    WHERE deptno = dept_no; 

    IF emp_cnt = 0 
    THEN 
     del_dept (dept_no); 
    END IF; 
END; 
+0

あなたのコードとコメントをありがとう!宿題の要件は、手続きの代わりにトリガーを書くことです。 – user7770852

+0

さて、トリガーをコンパイルして、私がやったことに従うことができればいいと言います。しかし、あなたがそれを実行するとき、あなたは問題に直面します。だから、宿題であれば、あなたが達成しようとしているものはそれを行う正しい方法ではありません。 – XING

関連する問題