PL/SQL LOOP문에서 예외가 발생하였을 때 처리 방법 추천~

PL/SQL의 LOOP에서 예외 처리를 적절하게 하는 방법을 설명하겠습니다. 예외 처리를 제대로 하지 않으면 프로그램이 예상치 못한 상황에서 멈추거나, 오류가 발생할 수 있기 때문에 적절히 연습해 두면 도움이 많이 될 거예요.

루프에서 예외 처리

  • 루프 내부에서 각각의 반복에 대한 예외를 개별적으로 처리할 수 있습니다.
  • 예외가 발생하였을 때, 루프 안에서 별도의 예외처리가 없다면, 반복에 대한 처리를 생략하고 다음 문장으로 넘어갑니다.
  • 예외가 너무 자주 발생하면 성능에 영향을 줄 수 있으므로 예외 발생 가능성을 최소화하는 것이 좋습니다.

예시 코드

SET SERVEROUTPUT ON

DECLARE
    -- 변수 선언
    emp_rec EMP%ROWTYPE; -- EMP 테이블의 한 레코드를 담을 변수
    tmp_count NUMBER;
    affected_department VARCHAR2(100);

    CURSOR emp_cur IS
        SELECT * FROM EMP;  -- EMP 테이블에서 모든 레코드를 조회하는 커서
BEGIN
    -- 커서 열기
    OPEN emp_cur;

    -- 루프 시작
    LOOP
        -- 데이터를 커서에서 가져오기
        FETCH emp_cur INTO emp_rec;

        -- 데이터가 없으면 루프 종료
        EXIT WHEN emp_cur%NOTFOUND;

        BEGIN
            -- 예외가 발생할 수 있는 SQL 구문
            SELECT COUNT(*), dname
            INTO tmp_count, affected_department
            FROM DEPT
            WHERE deptno = emp_rec.deptno;

            -- 추가적인 로직 처리
            DBMS_OUTPUT.PUT_LINE('사원: ' || emp_rec.ename || ', 부서: ' || affected_department || ', 직원 수: ' || tmp_count);

        EXCEPTION
            WHEN NO_DATA_FOUND THEN
                -- 데이터를 찾지 못한 경우 로그 남기고 계속 진행
                DBMS_OUTPUT.PUT_LINE('부서 데이터를 찾을 수 없습니다: ' || emp_rec.ename || ' (사원번호: ' || emp_rec.empno || ')');
                CONTINUE;

            WHEN OTHERS THEN
                -- 기타 예외 발생 시 처리
                DBMS_OUTPUT.PUT_LINE('예상치 못한 오류가 발생했습니다: ' || '사원: ' || RPAD(emp_rec.ename, 10, ' ') || ' 예외: '|| SQLERRM);
                CONTINUE;
        END;
    END LOOP;

    -- 커서 닫기
    CLOSE emp_cur;
EXCEPTION WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/
예상치 못한 오류가 발생했습니다: 사원: BLAKE      예외: ORA-00937: not a single-group group function
예상치 못한 오류가 발생했습니다: 사원: CLARK      예외: ORA-00937: not a single-group group function
예상치 못한 오류가 발생했습니다: 사원: JONES      예외: ORA-00937: not a single-group group function
예상치 못한 오류가 발생했습니다: 사원: SCOTT      예외: ORA-00937: not a single-group group function
예상치 못한 오류가 발생했습니다: 사원: FORD       예외: ORA-00937: not a single-group group function
예상치 못한 오류가 발생했습니다: 사원: SMITH      예외: ORA-00937: not a single-group group function
예상치 못한 오류가 발생했습니다: 사원: ALLEN      예외: ORA-00937: not a single-group group function
예상치 못한 오류가 발생했습니다: 사원: WARD       예외: ORA-00937: not a single-group group function
예상치 못한 오류가 발생했습니다: 사원: MARTIN     예외: ORA-00937: not a single-group group function
예상치 못한 오류가 발생했습니다: 사원: TURNER     예외: ORA-00937: not a single-group group function
예상치 못한 오류가 발생했습니다: 사원: ADAMS      예외: ORA-00937: not a single-group group function
예상치 못한 오류가 발생했습니다: 사원: JAMES      예외: ORA-00937: not a single-group group function
예상치 못한 오류가 발생했습니다: 사원: MILLER     예외: ORA-00937: not a single-group group function
예상치 못한 오류가 발생했습니다: 사원: KING       예외: ORA-00937: not a single-group group function

PL/SQL procedure successfully completed.

코드 설명

  1. SET SERVEROUTPUT ON:

    • DBMS_OUTPUT.PUT_LINE으로 출력된 메시지를 화면에 표시하기 위해 서버 출력 기능을 활성화하는 명령어입니다. PL/SQL에서 디버깅이나 로그 출력을 확인할 때 사용합니다.
  2. 변수 선언:

    • emp_rec EMP%ROWTYPE: EMP 테이블의 한 행(레코드)을 담을 수 있는 변수입니다. %ROWTYPE은 해당 테이블 구조에 맞는 데이터를 저장할 수 있도록 해 줍니다.
    • tmp_count NUMBER: 부서별 직원 수를 저장하는 변수입니다.
    • affected_department VARCHAR2(100): 부서 이름을 저장하는 변수입니다.
  3. 커서 선언:

    • CURSOR emp_cur IS SELECT * FROM EMP: EMP 테이블에서 모든 레코드를 조회하는 커서를 선언합니다. 이 커서는 이후 루프에서 사용되어 각 사원 데이터를 처리합니다.
  4. BEGIN 블록 시작 (프로그램 본체):

    • OPEN emp_cur: 커서를 열어 데이터를 조회할 준비를 합니다.
    • LOOP: 커서를 이용해 EMP 테이블의 각 레코드를 하나씩 처리하기 위한 루프입니다.
  5. 루프 내부 처리:

    • FETCH emp_cur INTO emp_rec: emp_cur 커서를 사용하여 EMP 테이블의 데이터를 한 줄씩 가져와서 emp_rec 변수에 저장합니다.
    • EXIT WHEN emp_cur%NOTFOUND: 더 이상 가져올 데이터가 없을 경우 루프를 종료합니다.
  6. 부서 정보 조회 (내부 BEGIN-END 블록):

    • SELECT COUNT(*), dname INTO tmp_count, affected_department FROM DEPT WHERE deptno = emp_rec.deptno:
      • EMP 테이블에서 가져온 사원의 부서 번호(emp_rec.deptno)를 이용하여, DEPT 테이블에서 해당 부서의 이름(dname)과 부서 내의 사원 수를 조회합니다.
      • 조회한 결과는 각각 tmp_countaffected_department 변수에 저장됩니다.
    • DBMS_OUTPUT.PUT_LINE: 결과를 출력합니다. 사원의 이름, 부서 이름, 해당 부서의 직원 수를 화면에 출력합니다.
  7. 예외 처리 (내부 예외 처리 블록):

    • WHEN NO_DATA_FOUND THEN:
      • 만약 DEPT 테이블에서 사원의 부서 번호에 해당하는 데이터를 찾지 못한 경우(NO_DATA_FOUND 예외), 사원 이름과 사원 번호를 출력하면서 경고 메시지를 남깁니다.
      • CONTINUE로 인해 루프는 다음 사원의 데이터를 처리하게 됩니다.
    • WHEN OTHERS THEN:
      • 기타 다른 예외가 발생한 경우(OTHERS 예외), 발생한 오류 메시지를 출력합니다. 이때, SQLERRM을 통해 구체적인 오류 메시지를 확인할 수 있습니다.
  8. 루프 종료 및 커서 닫기:

    • CLOSE emp_cur: 커서에서 모든 데이터를 처리한 후 커서를 닫습니다. 커서를 열었을 때 반드시 닫아주는 것이 좋습니다.
  9. 외부 예외 처리 (전체 블록 예외 처리):

    • 루프 밖에서, 프로그램 전체에서 발생할 수 있는 예외를 처리합니다.
    • EXCEPTION WHEN OTHERS THEN: 루프 바깥에서 발생한 예외를 처리하며, 발생한 오류 메시지를 출력합니다. 예를 들어, 커서를 여는 과정이나 닫는 과정에서 발생하는 오류가 있을 때 이 블록에서 처리됩니다.

결론

예외 처리를 잘 관리하면 루프 내에서 발생할 수 있는 오류를 효율적으로 처리하고 프로그램이 멈추지 않도록 할 수 있어요. 예외 처리에 관한 요구 수준을 확인하여 적절히 적용해 주세요~

필요에 따라 구체적인 예외를 나누어야 하는 경우도 있답니다. 특히 로그를 통해 어떤 오류가 발생했는지 추적할 수 있도록 하는 것은 도움이 많이 될 거예요.

이전최근
댓글 쓰기
가져가실 때, 출처 표시 부탁드려요! 감사합니다. 💗