2017-04-03 55 views
0

我需要創建一個觸發器,當從該emp表中刪除該部門的最後一名員工時,該部門將從部門表中刪除。
EMP(EMPNO,ENAME,DEPTNO)
部門(DEPTNO,DNAME)PLSQL_trigger不能編輯

首先,我創建的刪除從給定的deptno dept表的部門的過程。

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

然後,我創建時在該部門的最後EMP被刪除的刪除部門的觸發器。我試圖通過刪除deptno10中的三個emp中的一個來測試觸發器,但是我得到了來自命令的錯誤mesg,該觸發器無效且重新驗證失敗。

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

嗨,這是不是觸發刪除它好辦法,這樣做在窗體或應用程序,它確實在**從EMP表中刪除**刪除完成後 – hmmftg

+0

權是什麼這需要'FOR'循環嗎?當你調用'del_dept'時,'g_dno'的值是多少? – Nitish

+0

我的FOR循環的原因是檢查該部門中的每個emp。如果不是最後一個emp,只需刪除emp而不是該部門。我想我不需要觸發器來檢查這種情況。 g_dno的值是:old.deptno。我迷惑IN參數與OUT參數。在調用過程/函數時,我需要提供IN參數的值。在這裏,g_dno是一個IN參數。因此,我需要在調用例程中提供該值:old.deptno。 – user7770852

回答

0

錯誤trigger is invalid and failed re-validation指定侑觸發與編譯錯誤創建,因此你無法對它進行測試。在你的案例中寫一個觸發器不是一個好主意。我可以在代碼中看到幾個問題。所以我們先解決這些問題。

當你編寫下面的代碼時,你的觸發器將被編譯並且是有效的。所以,你不會得到錯誤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; 

但是當你將嘗試執行它,你將得到進一步的錯誤:

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'

之所以出現此錯誤是你從試圖selecttable從中你是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