2012-11-22 19 views
4

這個觸發器會將插入的值傳遞給一個過程,該過程會將這些值插入到另一個表中。我得到一個變異表錯誤。我怎樣才能解決這個問題?我該如何解決這個過程中的突變表觸發器

CREATE OR REPLACE TRIGGER ADD_INVOICE 
BEFORE INSERT OR UPDATE OF APP_NO,C_NO ON APPOINTMENT 
FOR EACH ROW 
DECLARE 
BEGIN 

POP_INVOICE(:NEW.APP_NO,:NEW.C_NO,:NEW.APP_DATE); 

END; 
/

CREATE OR REPLACE PROCEDURE POP_INVOICE(
I_APP_NO IN INVOICE.APP_NO%TYPE, 
I_C_NO IN INVOICE.C_NO%TYPE, 
I_INV_DATE IN INVOICE.INV_DATE%TYPE) 
AS 
CURSOR C_POP IS SELECT PRICE FROM TREATMENT T,APPOINTMENT A 
WHERE T.TRT_NO=A.TRT_NO 
AND A.APP_NO=I_APP_NO; 

V_BILL INVOICE.BILL%TYPE; 
BEGIN 

OPEN C_POP; 
FETCH C_POP INTO V_BILL; 

UPDATE INVOICE 
SET INV_NO=INV_IDSEQ.NEXTVAL, 
APP_NO=I_APP_NO, 
C_NO=I_C_NO, 
BILL=V_BILL, 
INV_DATE=I_INV_DATE; 

END; 
/
+2

順便說一句,你的UPDATE語句將在您的發票更新表中的每一行。 – DCookie

+1

我想你想要一個INSERT語句,而不是一個UPDATE。 –

回答

8

該問題是由在觸發器本身內引用帶有觸發器的表引起的。通過更改過程以接受TRT_NO作爲參數,不需要在查詢中包含APPOINTMENT,這樣可以避免變異表異常。根據每次治療的記錄數量,您甚至可以將光標合併到UPDATE語句中。

我認爲這應該做到這一點,雖然我一直無法檢查數據庫。

CREATE OR REPLACE TRIGGER ADD_INVOICE 

BEFORE INSERT OR UPDATE OF APP_NO,C_NO ON APPOINTMENT 
FOR EACH ROW 
DECLARE 
BEGIN 

POP_INVOICE(:NEW.APP_NO,:NEW.C_NO,:NEW.APP_DATE,:NEW.TRT_NO); 

END; 
/

修訂程序:

CREATE OR REPLACE PROCEDURE POP_INVOICE(
I_APP_NO IN INVOICE.APP_NO%TYPE, 
I_C_NO IN INVOICE.C_NO%TYPE, 
I_INV_DATE IN INVOICE.INV_DATE%TYPE, 
I_TRT_NO IN APPOINTMENT.TRT_NO%TYPE 
) 
AS 

CURSOR C_POP IS SELECT PRICE 
FROM TREATMENT T 
WHERE T.TRT_NO = I_TRT_NO; 

V_BILL INVOICE.BILL%TYPE; 

BEGIN 

OPEN C_POP; 
FETCH C_POP INTO V_BILL; 
CLOSE C_POP; 

INSERT INVOICE 
    (inv_no, app_no, c_no, bill, inv_date) 
VALUES 
    (INV_IDSEQ.NEXTVAL, I_APP_NO, I_C_NO, V_BILL, I_INV_DATE); 


END; 
/
+4

我已經自由地將UPDATE更正爲INSERT,因爲UPDATE沒有意義。 –

+0

非常感謝您的幫助 – Shimmerstrike