2016-10-14 50 views
1

我有這樣如何前或觸發之後創建一個能趕上DUP_VAL_ON_INDEX在Oracle PL/SQL

KD_C KD_PLA KD_T  GABUNG BERAKHIR GAJI_PL  BUYOUT 
---- ------ ---- ---------- ---------- ---------- ---------- 
C001 MA001 T006  2003  2014  50000 5200000 
C002 SC001 T006  2012  2016  65000 20280000 
C003 TW001 T006  2005  2018  90000 46800000 
C004 TV001 T006  2008  2017  60000 24960000 
C005 PC001 T001  2003  2016  80000 24960000 
C006 AC001 T001  1996  2014  90000 9360000 
C007 DB001 T001  2010  2016  65000 20280000 
C008 EH001 T001  2011  2018  85000 44200000 
C009 JC001 T002  1996  2014  60000 6240000 
C010 SG001 T002  1998  2016  87000 27144000 
C011 LS001 T002  2010  2018  81000 42120000 
C012 PR001 T002  2004  2016  60000 18720000 
C013 JH001 T003  2005  2018  72000 37440000 
C014 GC001 T003  2003  2015  65000 13520000 
C015 ED001 T003  2010  2018  100000 52000000 
C016 GB001 T003  2010  2016  80000 24960000 
C017 DG001 T004  2011  2018  73000 37960000 
C018 RG001 T004  1992  2014  90000 9360000 
C019 PJ001 T004  2011  2018  80000 41600000 
C020 RP001 T004  2012  2017  92000 38272000 
C021 GB002 T005  2006  2018  102000 53040000 
C022 EA001 T005  2011  2015  70000 14560000 
C023 HL001 T005  2012  2018  65000 33800000 
C024 KW001 T005  2009  2017  67000 27872000 
C025 MA001 T005  2017  2022  50000 26000000 
C028 MA001 T001  2016  2018  15000 3120000 
C029 MA001 T001  2016  2018  15000 3120000 
C030 MA001 T001  2016  2018  15000 3120000 

然後一表我試圖讓一個觸發更新,而不是插入到表時複製主鍵。主要關鍵是第一個顏色'KD_CONTRACT'。

CREATE OR REPLACE TRIGGER INSERT_TABEL_CONTRACT 
BEFORE INSERT ON CONTRACT 
FOR EACH ROW 
DECLARE 
    KODE VARCHAR2(20); 
    TEMPCARIKODE NUMBER; 
BEGIN 
    SELECT LPAD(TO_NUMBER(NVL(SUBSTR(MAX(KD_CONTRACT),2),0))+1,3,'0') INTO KODE 
    FROM CONTRACT; 

    SELECT COUNT(KD_CONTRACT) INTO TEMPCARIKODE 
    FROM CONTRACT 
    WHERE KD_CONTRACT = :NEW.KD_CONTRACT; 

    IF(TEMPCARIKODE = 0) THEN  
     :NEW.KD_CONTRACT := 'C'||KODE; 
     :NEW.GABUNG := TO_NUMBER(TO_CHAR(SYSDATE,'YYYY')); 
     :NEW.BERAKHIR := :NEW.GABUNG + :NEW.BERAKHIR; 
     :NEW.BUYOUT := (:NEW.GAJI_PL * 52) * (:NEW.Berakhir-:NEW.Gabung) * 2; 
    END IF; 
EXCEPTION 
    WHEN DUP_VAL_ON_INDEX THEN 
     DBMS_OUTPUT.PUT_LINE(''); 
     DBMS_OUTPUT.PUT_LINE(''); 
     DBMS_OUTPUT.PUT_LINE('ERROR at Line 1:'); 
     DBMS_OUTPUT.PUT_LINE('ORA-20003: Data sudah ada, data akan diupdate!'); 
END; 
/
show err; 

無論如何,也許代碼顯示,我試圖不更新時,主鍵是重複的。但請先到最後。

它顯示沒有錯誤...所以觸發器成功創建。 然後我試圖插入一個重複的主鍵。 INSERT INTO CONTRACT VALUES('C001','MA001','T001',2013,2,15000,2500000);

結果

INSERT INTO CONTRACT VALUES('C001','MA001','T001',2013,2,15000,2500000) 
* 
ERROR at line 1: 
ORA-00001: unique constraint (TUGAS.PK_CONTRACT) violated 

它確實提高ORA-00001,但它從來不碰DUP_VAL_ON_INDEX並表明沒有或自定義消息。 任何人都有想法?當它甚至從來沒有觸及DUP_VAL_ON_INDEX,那麼我怎麼能在事件粘貼更新查詢時... 謝謝... *無論如何,我的oracle是XE或快遞版。

+0

觸發器代碼不會拋出'dup_val_on_index',因此您的異常處理程序將永遠不會被調用。約束違規檢查與觸發器完全分離。如果你想捕捉錯誤,無論代碼中有什麼'insert'語句都需要有一個異常處理程序。 –

+0

你想得到什麼?乍一看,您嘗試使用獨特的「KD_CONTRACT」插入值。如果我是對的,則更適合使用序列。 –

+0

@MichaelPiankov啊這是回答我的問題..然後,我必須找到另一種方式。謝謝! –

回答

0

由於您的觸發器不包含任何INSERTUPDATE語句,觸發器中的EXCEPTION塊將永遠不會執行。 您必須考慮使用INSTEAD OF觸發器。

+0

好的。我能否使用BEFORE On工作? –