현상
merge문 수행 시 각각의 행 트리거(for each row)는 수행되지만 문장 트리거(after stmt trigger)가 수행되지 않는 현상이 발생했습니다.
(수행 시 별도 에러는 발생하지 않고, merge 문 내 insert, update 등 이벤트가 수행되지 않았습니다.)
원인
현재 merge 문 처리 과정에서 문장 트리거 동작 로직이 구현되어 있지 않았던 점 때문에 해당 오류 현상이 발생했습니다.
해결
1.
패치를 적용해 해결합니다. (적용 패치: 343434a)
주의
티맥스티베로에서 제공하는 기술지원을 통해 패치를 적용합니다.
2.
우회 방안을 설정하여 오류 해결을 시도할 수 있습니다.
•
우회 방안: merge 문 대신 조건을 추가하여 insert, update 문으로 수정하는 방법이 있습니다.
참고
merge문 수행 시 문장 트리거가 수행되지 않는 현상
-- #메인 테이블
CREATE TABLE E01_SITE_SUPPLIER_ITEM_VER (
SITE_CODE VARCHAR2(10),
AFFILIATE_CODE VARCHAR2(10),
SUPPLIER_CODE VARCHAR2(10),
ITEM_CODE VARCHAR2(10),
APPROVE_DATETIME DATE
);
-- #결과 테이블
CREATE TABLE EAI_E01_ITEM_APPROVE (
EAI_ROW_SEQ NUMBER,
SITE_CODE VARCHAR2(10),
AFFILIATE_CODE VARCHAR2(10),
SUPPLIER_CODE VARCHAR2(10),
ITEM_CODE VARCHAR2(10),
ITEM_VER_SEQ NUMBER,
STATUS_DATE VARCHAR2(8),
STATUS_TIME VARCHAR2(6),
STATUS_CODE VARCHAR2(10),
STATUS_NAME VARCHAR2(50),
SEND_STATUS_CODE VARCHAR2(1)
);
-- #시퀀스
CREATE SEQUENCE EAI_E01_ITEM_APPROVE_SEQ START WITH 1 INCREMENT BY 1;
-- #패키지
CREATE OR REPLACE PACKAGE PKG_SUPPLIER_ITEM AS
TYPE supplier_item_rec IS RECORD (
SITE_CODE VARCHAR2(10),
AFFILIATE_CODE VARCHAR2(10),
SUPPLIER_CODE VARCHAR2(10),
ITEM_CODE VARCHAR2(10)
);
TYPE supplier_item_tab IS TABLE OF supplier_item_rec INDEX BY PLS_INTEGER;
v_supplier_item supplier_item_tab;
PROCEDURE SP_ADD_SUPPLIER_ITEM(
vSiteCode VARCHAR2,
vAffiliateCode VARCHAR2,
vSupplierCode VARCHAR2,
vItemCode VARCHAR2
);
PROCEDURE SP_UPDATE_SUPPLIER;
END PKG_SUPPLIER_ITEM;
/
CREATE OR REPLACE PACKAGE BODY PKG_SUPPLIER_ITEM AS
PROCEDURE SP_ADD_SUPPLIER_ITEM(
vSiteCode VARCHAR2,
vAffiliateCode VARCHAR2,
vSupplierCode VARCHAR2,
vItemCode VARCHAR2
) IS
idNum PLS_INTEGER;
BEGIN
idNum := NVL(v_supplier_item.LAST, 0) + 1;
v_supplier_item(idNum).SITE_CODE := vSiteCode;
v_supplier_item(idNum).AFFILIATE_CODE := vAffiliateCode;
v_supplier_item(idNum).SUPPLIER_CODE := vSupplierCode;
v_supplier_item(idNum).ITEM_CODE := vItemCode;
END SP_ADD_SUPPLIER_ITEM;
PROCEDURE SP_UPDATE_SUPPLIER IS
v_index PLS_INTEGER;
BEGIN
v_index := v_supplier_item.FIRST;
WHILE v_index IS NOT NULL LOOP
INSERT INTO EAI_E01_ITEM_APPROVE (
EAI_ROW_SEQ, SITE_CODE, AFFILIATE_CODE, SUPPLIER_CODE, ITEM_CODE
) VALUES (
EAI_E01_ITEM_APPROVE_SEQ.NEXTVAL,
v_supplier_item(v_index).SITE_CODE,
v_supplier_item(v_index).AFFILIATE_CODE,
v_supplier_item(v_index).SUPPLIER_CODE,
v_supplier_item(v_index).ITEM_CODE
);
v_index := v_supplier_item.NEXT(v_index);
END LOOP;
v_supplier_item.DELETE;
END SP_UPDATE_SUPPLIER;
END PKG_SUPPLIER_ITEM;
/
-- #행 트리거
CREATE OR REPLACE TRIGGER TRG_E01_SUPPLIER_ITEM_VER_ROW
AFTER INSERT ON E01_SITE_SUPPLIER_ITEM_VER
FOR EACH ROW
BEGIN
PKG_SUPPLIER_ITEM.SP_ADD_SUPPLIER_ITEM(
:NEW.SITE_CODE,
:NEW.AFFILIATE_CODE,
:NEW.SUPPLIER_CODE,
:NEW.ITEM_CODE
);
END;
/
-- # 문장 트리거
CREATE OR REPLACE TRIGGER TRG_E01_SUPPLIER_ITEM_VER_STMT
AFTER INSERT ON E01_SITE_SUPPLIER_ITEM_VER
BEGIN
PKG_SUPPLIER_ITEM.SP_UPDATE_SUPPLIER;
END;
/
-- #기존에 데이터가 있을 경우 삭제
DELETE FROM E01_SITE_SUPPLIER_ITEM_VER;
delete from EAI_E01_ITEM_APPROVE;
COMMIT;
-- #merge 문 수행
MERGE INTO E01_SITE_SUPPLIER_ITEM_VER t
USING (SELECT 'S001' SITE_CODE, 'A001' AFFILIATE_CODE, 'SUP001' SUPPLIER_CODE, 'ITM001' ITEM_CODE FROM DUAL) s
ON (t.SITE_CODE = s.SITE_CODE AND t.AFFILIATE_CODE = s.AFFILIATE_CODE AND t.ITEM_CODE = s.ITEM_CODE)
WHEN NOT MATCHED THEN
INSERT (SITE_CODE, AFFILIATE_CODE, SUPPLIER_CODE, ITEM_CODE, APPROVE_DATETIME)
VALUES (s.SITE_CODE, s.AFFILIATE_CODE, s.SUPPLIER_CODE, s.ITEM_CODE, SYSDATE);
1 row merged. -> 에러 없이 정상 수행
-- #merge문 수행 후 결과 확인
SELECT * FROM EAI_E01_ITEM_APPROVE;
0 rows selected. -> 결과 값 없음
-- #merge문 대신, insert문으로 수행
INSERT into E01_SITE_SUPPLIER_ITEM_VER (SITE_CODE, AFFILIATE_CODE, SUPPLIER_CODE, ITEM_CODE, APPROVE_DATETIME)
VALUES ('a', 'b', 'c', 'd', sysdate);
1 rows inserted. -> 에러 없이 정상 수행
-- #insert문 수행 후 결과 확인
SELECT * FROM EAI_E01_ITEM_APPROVE;
EAI_ROW_SEQ SITE_CODE AFFILIATE_CODE SUPPLIER_CODE ITEM_CODE ITEM_VER_SEQ
STATUS_DATE STATUS_TIME STATUS_CODE
STATUS_NAME SEND_STATUS_CODE
8 S001 A001 SUP001 ITM001
9 a b c d</code></pre>
SQL
복사