'ORA-00036: maximum number of recursive sql levels (50) exceeded' 오류는 문자 그대로 재귀 SQL 레벨이 최대 허용치를 초과했을 때 발생합니다. 이 오류는 일반적으로 재귀 트리거가 너무 깊게 호출되어 발생하며, 이를 해결하기 위해 재귀 트리거를 제거하거나 조정해야 합니다! 😊 자, 그러면 살펴보도록 하겠습니다~
ORA-00036 오류 원인
재귀 SQL 트리거가 너무 깊게 호출되어 최대 재귀 레벨을 초과했을 때 발생합니다.
ORA-00036 해결 방법
재귀 트리거를 제거하거나, 재귀 호출을 줄여 재귀 깊이를 줄입니다. 보통 재귀 함수를 잘못 사용하여 발생하는 경우가 많은데요, 예시를 한 번 살펴보도록 하겠습니다.
아래 예시에서 {EMP} 테이블에서 재귀 트리거로 인해 'ORA-00036' 오류가 발생하는 상황을 보여드리겠습니다. 다음과 같이 재귀 트리거로 인한 오류가 발생하는 상황을 보시지요. 😊
CREATE OR REPLACE TRIGGER emp_before_insert
BEFORE INSERT ON EMP
FOR EACH ROW
BEGIN
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (:NEW.EMPNO + 1, :NEW.ENAME, :NEW.JOB, :NEW.MGR, SYSDATE, :NEW.SAL, :NEW.COMM, :NEW.DEPTNO);
END;
/
Trigger created.
이제, {EMP} 테이블을 업데이트하면 트리거가 재귀적으로 호출되어 'ORA-00036' 오류가 발생할 수 있습니다. '비포어 인서트' 라는 단서를 남겼으므로, 인서트 하려는 순간 트리거에 의해 계속하여 EMP 테이블에 인서트를 시도하려고 할 것입니다.
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (1, 'BEOMSANG', 'DEV', 7839, SYSDATE, 1, NULL, 10);
ERROR at line 1:
ORA-00036: maximum number of recursive SQL levels (50) exceeded
ORA-06512: at "USER_NAME.EMP_BEFORE_INSERT", line 2
ORA-04088: error during execution of trigger 'USER_NAME.EMP_BEFORE_INSERT'
ORA-06512: at "USER_NAME.EMP_BEFORE_INSERT", line 2
ORA-04088: error during execution of trigger 'USER_NAME.EMP_BEFORE_INSERT'
ORA-06512: at "USER_NAME.EMP_BEFORE_INSERT", line 2
ORA-04088: error during execution of trigger 'USER_NAME.EMP_BEFORE_INSERT'
ORA-06512: at "USER_NAME.EMP_BEFORE_INSERT", line 2
ORA-04088: error during execution of trigger 'USER_NAME.EMP_BEFORE_INSERT'
ORA-06512: at "USER_NAME.EMP_BEFORE_INSERT", line 2
ORA-04088: error during execution of trigger 'USER_NAME.EMP_BEFORE_INSERT'
ORA-06512: at "USER_NAME.EMP_BEFORE_INSERT", line 2
ORA-04088: error during execution of trigger 'USER_NAME.EMP_BEFORE_INSERT'
ORA-06512: at "USER_NAME.EMP_BEFORE_INSERT", line 2
ORA-04088: error during execution of trigger 'USER_NAME.EMP_BEFORE_INSERT'
ORA-06512: at "USER_NAME.EMP_BEFORE_INSERT", line 2
해결 방법으로는, 재귀 트리거를 드랍하거나 예상 가능한 재귀 레벨 내에서 호출하도록 트리거를 조정해야 합니다.
트리거 내에서 동일한 테이블 접근 피하기
ORA-00036 오류를 해결하려면 트리거 내에서 동일한 테이블에 대해 직접적인 INSERT, UPDATE 등의 작업을 피하는 것입니다. 대신 다른 테이블에 로그를 남기거나, 테이블을 분리하여 처리하는 방법을 검토해 주세요. 트리거를 작성할 때는 이러한 무한 루프 상황을 피하기 위해 신중하게 설계하는 것이 중요해요~ 😊
재귀 호출 제한하기
재귀 호출을 제한하는 방법을 사용하여 트리거가 특정 조건에서만 동작하도록 조정할 수 있습니다. 예를 들어, 재귀 호출을 막기 위해 추가적인 조건을 설정합니다.
CREATE OR REPLACE TRIGGER emp_before_insert
BEFORE INSERT ON EMP
FOR EACH ROW
BEGIN
IF :NEW.EMPNO < 3 THEN
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (:NEW.EMPNO + 1, :NEW.ENAME, :NEW.JOB, :NEW.MGR, SYSDATE, :NEW.SAL, :NEW.COMM, :NEW.DEPTNO);
END IF;
END;
/
Trigger created.
이렇게 하면 트리거가 재귀적으로 호출되는 상황을 줄일 수 있습니다. 물론, 예시를 위한 조건이므로 실제로 이렇게 특이한 조건을 설정하지는 않을 것입니다. 😅
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (1, 'BEOMSANG', 'DEV', 7839, SYSDATE, 1, NULL, 10);
1 row created.
SELECT * FROM EMP;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- -------------------- ------------------ ---------- -------- ---------- ---------- ----------
3 BEOMSANG DEV 7839 01/01/01 1 10
2 BEOMSANG DEV 7839 01/01/01 1 10
1 BEOMSANG DEV 7839 01/01/01 1 10
7698 BLAKE MANAGER 7839 91/01/05 2850 30
7782 CLARK MANAGER 7839 99/09/06 2450 10
7566 JONES MANAGER 7839 01/02/04 2975 20
7788 SCOTT ANALYST 7566 03/06/17 3000 20
7902 FORD ANALYST 7566 81/03/12 3000 20
7369 SMITH CLERK 7902 07/12/01 800 20
7499 ALLEN SALESMAN 7698 81/02/20 1600 300 30
7521 WARD SALESMAN 7698 81/02/22 1250 500 30
7654 MARTIN SALESMAN 7698 81/09/28 1250 1400 30
7844 TURNER SALESMAN 7698 81/08/09 1500 0 30
7876 ADAMS CLERK 7788 87/05/23 1100 20
7900 JAMES CLERK 7698 81/03/12 950 30
7934 MILLER CLERK 7782 03/01/23 1300 10
7839 KING PRESIDENT 96/11/17 5000 10
17 rows selected.
