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.
코드 설명
SET SERVEROUTPUT ON:DBMS_OUTPUT.PUT_LINE으로 출력된 메시지를 화면에 표시하기 위해 서버 출력 기능을 활성화하는 명령어입니다. PL/SQL에서 디버깅이나 로그 출력을 확인할 때 사용합니다.
변수 선언:
emp_rec EMP%ROWTYPE:EMP테이블의 한 행(레코드)을 담을 수 있는 변수입니다.%ROWTYPE은 해당 테이블 구조에 맞는 데이터를 저장할 수 있도록 해 줍니다.tmp_count NUMBER: 부서별 직원 수를 저장하는 변수입니다.affected_department VARCHAR2(100): 부서 이름을 저장하는 변수입니다.
커서 선언:
CURSOR emp_cur IS SELECT * FROM EMP:EMP테이블에서 모든 레코드를 조회하는 커서를 선언합니다. 이 커서는 이후 루프에서 사용되어 각 사원 데이터를 처리합니다.
BEGIN 블록 시작 (프로그램 본체):
OPEN emp_cur: 커서를 열어 데이터를 조회할 준비를 합니다.LOOP: 커서를 이용해EMP테이블의 각 레코드를 하나씩 처리하기 위한 루프입니다.
루프 내부 처리:
FETCH emp_cur INTO emp_rec:emp_cur커서를 사용하여EMP테이블의 데이터를 한 줄씩 가져와서emp_rec변수에 저장합니다.EXIT WHEN emp_cur%NOTFOUND: 더 이상 가져올 데이터가 없을 경우 루프를 종료합니다.
부서 정보 조회 (내부 BEGIN-END 블록):
SELECT COUNT(*), dname INTO tmp_count, affected_department FROM DEPT WHERE deptno = emp_rec.deptno:EMP테이블에서 가져온 사원의 부서 번호(emp_rec.deptno)를 이용하여,DEPT테이블에서 해당 부서의 이름(dname)과 부서 내의 사원 수를 조회합니다.- 조회한 결과는 각각
tmp_count와affected_department변수에 저장됩니다.
DBMS_OUTPUT.PUT_LINE: 결과를 출력합니다. 사원의 이름, 부서 이름, 해당 부서의 직원 수를 화면에 출력합니다.
예외 처리 (내부 예외 처리 블록):
WHEN NO_DATA_FOUND THEN:- 만약
DEPT테이블에서 사원의 부서 번호에 해당하는 데이터를 찾지 못한 경우(NO_DATA_FOUND예외), 사원 이름과 사원 번호를 출력하면서 경고 메시지를 남깁니다. CONTINUE로 인해 루프는 다음 사원의 데이터를 처리하게 됩니다.
- 만약
WHEN OTHERS THEN:- 기타 다른 예외가 발생한 경우(
OTHERS예외), 발생한 오류 메시지를 출력합니다. 이때,SQLERRM을 통해 구체적인 오류 메시지를 확인할 수 있습니다.
- 기타 다른 예외가 발생한 경우(
루프 종료 및 커서 닫기:
CLOSE emp_cur: 커서에서 모든 데이터를 처리한 후 커서를 닫습니다. 커서를 열었을 때 반드시 닫아주는 것이 좋습니다.
외부 예외 처리 (전체 블록 예외 처리):
- 루프 밖에서, 프로그램 전체에서 발생할 수 있는 예외를 처리합니다.
EXCEPTION WHEN OTHERS THEN: 루프 바깥에서 발생한 예외를 처리하며, 발생한 오류 메시지를 출력합니다. 예를 들어, 커서를 여는 과정이나 닫는 과정에서 발생하는 오류가 있을 때 이 블록에서 처리됩니다.
결론
예외 처리를 잘 관리하면 루프 내에서 발생할 수 있는 오류를 효율적으로 처리하고 프로그램이 멈추지 않도록 할 수 있어요. 예외 처리에 관한 요구 수준을 확인하여 적절히 적용해 주세요~
필요에 따라 구체적인 예외를 나누어야 하는 경우도 있답니다. 특히 로그를 통해 어떤 오류가 발생했는지 추적할 수 있도록 하는 것은 도움이 많이 될 거예요.
