CREATE OR REPLACE TRIGGER HOST_SCHOOL.MDAPPLCNT_TRG AFTER INSERT OR UPDATE OR DELETE ON HOST_SCHOOL.MDAPPLCNT FOR EACH ROW DECLARE v_APPLCNT_ID HOST_SCHOOL.MDAPPLCNT.APPLCNT_ID %TYPE ; v_APPLCNT_NM HOST_SCHOOL.MDAPPLCNT.APPLCNT_NM %TYPE ; v_CONFM_CODE HOST_SCHOOL.MDAPPLCNT.CONFM_CODE %TYPE ; v_FRST_REGISTER_ID HOST_SCHOOL.MDAPPLCNT.FRST_REGISTER_ID %TYPE ; v_FRST_REGIST_PNTTM HOST_SCHOOL.MDAPPLCNT.FRST_REGIST_PNTTM %TYPE ; v_LAST_UPDT_PNTTM HOST_SCHOOL.MDAPPLCNT.LAST_UPDT_PNTTM %TYPE ; v_LAST_UPDUSR_ID HOST_SCHOOL.MDAPPLCNT.LAST_UPDUSR_ID %TYPE ; v_REQST_DY HOST_SCHOOL.MDAPPLCNT.REQST_DY %TYPE ; v_REQST_ID HOST_SCHOOL.MDAPPLCNT.REQST_ID %TYPE ; v_USER_SEQ HOST_SCHOOL.MDAPPLCNT.USER_SEQ %TYPE ; v_USE_AT HOST_SCHOOL.MDAPPLCNT.USE_AT %TYPE ; v_NEW_CONFM_CODE HOST_SCHOOL.MDAPPLCNT.CONFM_CODE %TYPE ; CURSOR select_applicant_source IS SELECT a.APPLCNT_ID , a.APPLCNT_NM , a.CONFM_CODE , a.FRST_REGISTER_ID , a.FRST_REGIST_PNTTM , a.LAST_UPDT_PNTTM , a.LAST_UPDUSR_ID , a.REQST_DY , a.REQST_ID , a.USER_SEQ , a.USE_AT , (CASE WHEN ROW_NUMBER() OVER(ORDER BY a.REQST_DY ) <= r.PSNCPA THEN 'ACS002' ELSE NULL END) AS NEW_CONFM_CODE FROM HOST_SCHOOL.MDREQSTINFO r , HOST_SCHOOL.MDAPPLCNT a WHERE r.REQST_ID = a.REQST_ID AND r.CONFM_MTHD_CODE = 'REC001' AND a.USE_AT = 'Y' AND r.REQST_ID = :new.REQST_ID ; BEGIN OPEN select_applicant_source ; LOOP FETCH select_applicant_source INTO v_APPLCNT_ID , v_APPLCNT_NM , v_CONFM_CODE , v_FRST_REGISTER_ID , v_FRST_REGIST_PNTTM , v_LAST_UPDT_PNTTM , v_LAST_UPDUSR_ID , v_REQST_DY , v_REQST_ID , v_USER_SEQ , v_USE_AT , v_NEW_CONFM_CODE ; EXIT WHEN select_applicant_source%NOTFOUND ; UPDATE HOST_SCHOOL.MDAPPLCNT SET CONFM_CODE = v_NEW_CONFM_CODE ,LAST_UPDUSR_ID = 'trg' WHERE APPLCNT_ID = v_APPLCNT_ID AND REQST_ID = v_REQST_ID ; COMMIT; END LOOP ; EXCEPTION WHEN OTHERS THEN RAISE_APPLICATION_ERROR(-20002,v_APPLCNT_ID || '@@@@' || v_NEW_CONFM_CODE ||'@@@@:' || SQLERRM); END;
안녕하세요.
티베로6에서 트리거를 작성했습니다.
자신의테이블에 입력,수정,삭제가 발생하면 자신의테이블의 기존데이터를 업데이트 시키려고합니다.
컴파일은 됐는데 실행시 아래와 같은 에러가 발생합니다.
JDBC-20002:345@@@@@@@@:TBR-15095: Trigger/function cannot access table 'MDAPPLCNT' while it is being modified
감사합니다
업데이트 중인 테이블에 트리거를 걸었는데
트리거 안에서 업데이트를 치면
트리거가 무한루프를 돌겠지요.
그래서 무한루프 방지하기 위해 에러가 나는 것입니다.
행트리거 하나만 가지고 해결이 안됩니다.
문장 트리거와 행트리거를 적절하게 섞어서 구현하셔야 합니다.
http://gurubee.net/article/53504
다음과 같은 절차로 구현되어야 합니다.
1. 변경되는 reqst_id 를 담을 테이블타입의 패키지 변수 생성
2. Before 문장트리거에서 변수 초기화
3. 행 트리거에서 변수에 reqst_id 를 저장
4. After 문장트리거에서 해당 변수 루프 돌려가면서 해당 로직 수행
오라클 11G 부터는 compound trigger(복합 트리거)가 가능하여 트리거 여러개 작성 안해도 됩니다.
하나의 트리거 안에서 여러가지 타입의 트리거 구현이 가능합니다.
티베로에서도 위와 같이 구현이 가능한지 확인해 보세요.
하지만 위 복합 트리거 방법은 구현도 복잡하고 까다롭습니다.
트리거 가 아닌 프로그램에서 처리하는 방안은 없을지 고민해 보세요.