#oracle #plsql #oracle11g
#Oracle #plsql #oracle11g
Вопрос:
У меня есть такая таблица
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, как я могу вставить запрос на обновление в случае when…
Спасибо…
* в любом случае, мой oracle — XE или express edition.
Комментарии:
1. Код триггера не будет выдавать a
dup_val_on_index
, поэтому ваш обработчик исключений никогда не будет вызван. Проверка на нарушение ограничений полностью отделена от триггера. Если вы хотите перехватить ошибку, любой код, содержащийinsert
оператор, должен иметь обработчик исключений.2. что вы хотите получить? На первый взгляд вы пытаетесь вставить значения с помощью inique
KD_CONTRACT
. Если я прав, более подходящим является использование последовательности.3. @MichaelPiankov Ах, это ответ на мой вопрос.. Тогда я должен найти другой способ. Спасибо!
4. @BenyaminLimanto: если вопрос теперь бесполезен, пожалуйста, удалите его
Ответ №1:
EXCEPTION
Блок из вашего триггера никогда не будет выполнен, поскольку ваш триггер не содержит никаких INSERT
UPDATE
операторов or. Вместо этого вы должны рассмотреть INSTEAD OF
триггер.
Комментарии:
1. Хорошо. Могу ли я использовать вместо работы также с BEFORE On?