[PL/SQL] 시스템 예외(Exception) 처리 / 사용자 정의 예외 처리

EUN JY·2022년 8월 16일
1

Database

목록 보기
11/21

1. 예외 처리

  • 시스템 예외 : Oracle에서 예외 상황에 대해 미리 정의해놓은 예외
  • 사용자 정의 예외 : 예상되는 특정 예외 상황에 대해 개발자가 직접 정의한 예외
  • 처리할 예외들을 차례로 선언한 뒤, 마지막에 OTHERS를 선언하여 나머지 예외를 처리하도록 함
EXCEPTION WHEN [예외명1] THEN [예외처리 구문1]
WHEN [예외명2] THEN [예외처리 구문2];

1-1. 예외 처리

  • 프로시저 실행 후 예외가 발생하더라도 로직은 정상 작동되도록 예외 처리 구문 작성
CREATE OR REPLACE PROCEDURE PROC_TEST
IS
    v_num NUMBER := 0;
BEGIN
    v_num := 10/0;
    EXCEPTION WHEN OTHERS THEN 
        dbms_output.put_line('오류가 발생했습니다!');
        dbms_output.put_line('에러코드 : ' || SQLCODE);
        dbms_output.put_line('에러메시지 : ' || SQLERRM);
        dbms_output.put_line('매개변수 있는 에러메시지 : ' || SQLERRM(SQLCODE));
END;
/
EXEC PROC_TEST();
/* 결과
오류가 발생했습니다!
에러코드 : -1476
에러메시지 : ORA-01476: 제수가 0 입니다
매개변수 있는 에러메시지 : ORA-01476: 제수가 0 입니다 */

1-2. 시스템 예외

  • Oracle에서 지원하는 대표적 시스템 예외 목록
예외명예외 코드설명
PROGRAM_ERRORORA-06501PL/SQL 코드상에서 내부 오류를 만났을 경우
STORAGE_ERRORORA-06500프로그램 수행 시 메모리가 부족할 경우
TIMEOUT_ON_RESOURCEORA-00051데이터베이스 자원을 기다리는 동안 타임아웃 발생 시
NO_DATA_FOUNDORA-01403SELECT INTO 시 데이터가 한 건도 없을 경우
TOO_MANY_ROWSORA-01422SELECT INTO 절 사용할 때 결과가 한 로우 이상일 때
VALUE_ERRORORA-06502수치 또는 값 오류
ZERO_DIVIDEORA-014760으로 나눌 때
INVALID_NUMBERORA-01722문자를 숫자로 변환할 때 실패할 경우
DUP_VAL_ON_INDEXORA-00001유일 인덱스가 있는 컬럼에 중복값으로 INSERT, UPDATE 수행
CASE_NOT_FOUNDORA-06592CASE문 사용 시 구문 오류
ACCESS_INTO_NULLORA-06530LOB과 같은 객체 초기화 되지 않은 상태에서 사용
CURSOR_ALREADY_OPENORA-06511커서가 이미 OPEN 된 상태인데 OPEN 하려고 시도
INVALID_CURSORORA-01001존재하지 않는 커서를 참조
NOT_LOGGED_ONORA-01012로그온되지 않았는데 DB를 참조할 때
LOGIN_DENIEDORA-01017잘못된 사용자 이름이나 비밀번호로 로그인을 시도

1-3. 사용자 정의 예외

  • 입력 받은 값이 유효하지 않은 경우 예외 처리하도록 프로시저 구성
  • RAISE : 직접 정의한 예외, 시스템 예외를 발생시키기 위해 작성
    • ex_not_exist_num EXCEPTION; : 선언부에 작성하여 예외를 정의
    • RAISE NO_DATA_FOUND; : 시스템 예외를 발생시키도록 함
CREATE OR REPLACE PROCEDURE PROC_CHK_USER_NUM (p_user_num USER_INFO.USER_NUM%TYPE)
IS
    v_cnt NUMBER := 0;
    ex_not_exist_num EXCEPTION;
BEGIN
    SELECT COUNT(1)
    INTO v_cnt
    FROM USER_INFO 
    WHERE USER_NUM = p_user_num;
    
    -- 입력 데이터에 따른 결과값 조건 처리
    IF p_user_num = 1 THEN
        RAISE NO_DATA_FOUND;
    ELSIF v_cnt > 0 THEN 
        dbms_output.put_line('등록된 사용자입니다.');
    ELSE 
        RAISE ex_not_exist_num;
    END IF;
    
    -- 예외 처리
    EXCEPTION
    WHEN NO_DATA_FOUND THEN
        dbms_output.put_line('NO_DATA_FOUND!!');
    WHEN ex_not_exist_num THEN
        dbms_output.put_line('등록된 사용자가 없습니다.');
    WHEN OTHERS THEN
        dbms_output.put_line(SQLERRM);
END;
/

-- 결과 
EXEC PROC_CHK_USER_NUM(1); /* NO_DATA_FOUND!! */
EXEC PROC_CHK_USER_NUM(2); /* 등록된 사용자입니다. */
EXEC PROC_CHK_USER_NUM(111); /* 등록된 사용자가 없습니다. */
EXEC PROC_CHK_USER_NUM('YNJCH'); 
/* ORA-06502: PL/SQL: 수치 또는 값 오류: 문자를 숫자로 변환하는데 오류입니다 */

1-4. 예외 내용 확인

  • Oracle에서 기본 제공하는 빌트인(built-in) 함수 이용
    • SQLCODE : 실행부에서 발생한 예외에 해당하는 코드를 반환
    • SQLERRM : 예외에 대한 정보를 담은 메시지 반환
  • 상세 정보를 표시하기 위해 dbms_utility 이용
    • dbms_utility.format_call_stack
    • dbms_utility.format_error_stack
    • dbms_utility.format_error_backtrace

1-4-1. 효율적인 예외 처리 방법

  • 시스템 예외인 경우 OTHERS 사용
  • 예외 처리 루틴을 공통 모듈화하여, 예외 발생 시 로그를 기록하도록 테이블을 만들어 관리
  • 사용자 정의 예외는 별도 테이블을 만들어 관리
profile
개린이

0개의 댓글