merge문 오류인지 trigger 오류인지 모르겠습니다. 0 6 138

by 잘하자DBA [SQL Query] [2018.10.11 17:34:47]


GPPP057_ddl.txt (3,451Bytes)
GPPP001_ddl.txt (4,325Bytes)

MERGE INTO문을 사용하여 TRIGGER가 구동이 되는데 오류가 발생하여 문의드립니다.

MERGE INTO gppp001 tb_im
     USING (SELECT '1000' AS comp_cd, '6E75455' AS sty_cd FROM DUAL) tb_sys
        ON (tb_im.comp_cd = tb_sys.comp_cd AND tb_im.sty_cd = tb_sys.sty_cd)
WHEN NOT MATCHED
THEN
   INSERT     (comp_cd,
               org_comp_cd,
               sty_cd,
               plan_seq,
               in_user,
               in_time,
               upd_user,
               upd_time)
       VALUES ('1000',
               '1000',
               '6E75455',
               '001',
               'Z000034',
               SYSDATE,
               'Z000034',
               SYSDATE)

 

해당 MERGE문을 실행하면 GPPP001에 DATA가 없는데도 INSERT가 되지 않습니다.

참고로 11.2.0.2에서 11.2.0.4로 업그레이드 되고 나서 문제가 발생되었습니다.

11.2.0.2에서는 문제없이 되었습니다.

GPPP001에는 총 3개의 TRIGGER가 걸려있습니다.

그중 TR_GPPP001_CUST에서 for each row 옵션 유무에 따라

없으면 ORA-06502:PL/SQL: 수치 또는 값 오류 : NULL index table key value ORA-06512:"TEST.TR_GPPP001_CUST", 16행 ORA-04088: 트리거 :"TEST.TR_GPPP001_CUST"의 수행시 오류

있으면 위와 같이 TABLE에 DATA가 없어서 INSERT가 되어야 하는데 INSERT가 되지 않고 있습니다.

 

무엇이 잘못된 것인지 정말 궁금합니다.

by 마농 [2018.10.11 19:19:50]

글쎄요? for each row 가 있고 없고 차이는 엄청난 차이인데요?
이걸 넣었다가 뺐다 하면서 테스트 할 건 아니라고 생각됩니다.
일단 원상태(아마도 for each row 가 있는게 원상태 이겠죠?)로 돋려 놓으시고
에러메시지 보면서 대응 방법 생각하셔야 됩니다.
에러메시지 안나는데 입력만 안된다면?
혹시 에러 났는데 exception 절 때문에 그냥 넘어간걸 수도 있습니다.


by 잘하자DBA [2018.10.15 09:57:12]

네 답변 감사합니다. 원래 FOR EACH ROW가 없었던 트리거 입니다.


그래서 이관후 트리거 동작시 ORA-06502 에러가 떠서 그 문제를 해결하다보니 뒤늦게 FOR EACH ROW를 넣었습니다.


오라클 SR 진행 결과 DB 문제는 아니라고 하고 개발 이슈라고 하는데 어디가 문제인지 잘 몰라서 의견을 들어보고 싶었습니다.

 


by 마농 [2018.10.15 10:46:43]

문제 없이 잘 돌아가던 트리거라면?
for each row 를 임의로 붙이는 것은 잘못된 대응인듯 하구요.
해당 오류 메시지에 주목하세요. (ora-06502 : 수치 또는 값 오류)


by 잘하자DBA [2018.10.23 15:56:48]

항상 답변 감사드립니다.

네 for each row는 이관전부터 없었기 때문에 다시 원상복귀한 채로 test를 진행하고 있습니다.

근데 

11.2.0.2 DB에서 TEST해 보면 

merge문 실행시 WHEN NOT MATCHED 조건이 아닐 경우 TR_GPPP001_CUST TRIGGER에서 

BEGIN 

IF INSERTING THEN 부분을 타지 않고 빠져 나오는데 

11.2.0.4 DB에서 TEST해 보면 

merge문 실행시 WHEN NOT MATCHED 조건이 아닐 경우 TR_GPPP001_CUST TRIGGER에서 

IF INSERTING THEN 조건을 타고 그 밑에 IF 절을 또 타서 에러가 납니다. 

너무 희한한 증상이라 SR을 올려봐도 개발이슈니 그쪽에서 확인하라는 답변이 와서 답답하네요

일단 저는 MERGE구문에서 INSERT 조건이 아닌데도 불구하고 TR_GPPP001_CUST 트리거를 타는 이유를 먼저 모르겠습니다.

그리고 MERGE문에서 WHEN NOT MATCHED 조건인 경우 AS-IS DB인 경우
1. TR_GPPP001_BF_INSERT_COLL_GB  -> BEFORE INSERT 트리거

2. TR_GPPP001_AF_INSERT_COLL_GB -> AFTER INSERT 트리거

3. TR_GPPP001_CUST -> AFTER INSERT 트리거 

순으로 동작을 하는데

이관된 DB에서는 

1 -> 3번 (NO_DATA_FOUND) 에러 떨어집니다.   2번 트리거를 타지 않는 이유도 너무 궁금합니다.

한 테이블에서 다중으로 트리거가 동작하는 경우 무슨 순서를 지정하는게 있는건지 그것도 궁금합니다.


by 마농 [2018.10.23 16:39:35]

"이럴리가 없는데"라는 선입견을 버리고 에러 자체에 집중하세요.
안타야 할 IF 문이 탄다면? IF 문을 탈만한 이유가 있을 것입니다.
절대로 그럴리가 없다고 정하고 나면 해결책이 보이질 않습니다.
여러개 트리거의 동작 순서는
문장트리거인지? 행트리거(for each row)인지? before 인지? after 인지? 에 따라 결정될 것입니다.
1,2번 은 문장트리거 3번은 행트리거일 듯 합니다.
제 예상 순서는 1 > 3 > 2 입니다.
2번이 안타는 이유는 3번이 에러났기 때문이겠죠.


by 잘하자DBA [2018.10.24 13:39:01]

네 천천히 다시 한번 에러코드 위주로 보겠습니다.

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입