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();
1-2. 시스템 예외
- Oracle에서 지원하는 대표적 시스템 예외 목록
예외명 | 예외 코드 | 설명 |
---|
PROGRAM_ERROR | ORA-06501 | PL/SQL 코드상에서 내부 오류를 만났을 경우 |
STORAGE_ERROR | ORA-06500 | 프로그램 수행 시 메모리가 부족할 경우 |
TIMEOUT_ON_RESOURCE | ORA-00051 | 데이터베이스 자원을 기다리는 동안 타임아웃 발생 시 |
NO_DATA_FOUND | ORA-01403 | SELECT INTO 시 데이터가 한 건도 없을 경우 |
TOO_MANY_ROWS | ORA-01422 | SELECT INTO 절 사용할 때 결과가 한 로우 이상일 때 |
VALUE_ERROR | ORA-06502 | 수치 또는 값 오류 |
ZERO_DIVIDE | ORA-01476 | 0으로 나눌 때 |
INVALID_NUMBER | ORA-01722 | 문자를 숫자로 변환할 때 실패할 경우 |
DUP_VAL_ON_INDEX | ORA-00001 | 유일 인덱스가 있는 컬럼에 중복값으로 INSERT, UPDATE 수행 |
CASE_NOT_FOUND | ORA-06592 | CASE문 사용 시 구문 오류 |
ACCESS_INTO_NULL | ORA-06530 | LOB과 같은 객체 초기화 되지 않은 상태에서 사용 |
CURSOR_ALREADY_OPEN | ORA-06511 | 커서가 이미 OPEN 된 상태인데 OPEN 하려고 시도 |
INVALID_CURSOR | ORA-01001 | 존재하지 않는 커서를 참조 |
NOT_LOGGED_ON | ORA-01012 | 로그온되지 않았는데 DB를 참조할 때 |
LOGIN_DENIED | ORA-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);
EXEC PROC_CHK_USER_NUM(2);
EXEC PROC_CHK_USER_NUM(111);
EXEC PROC_CHK_USER_NUM('YNJCH');
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 사용
- 예외 처리 루틴을 공통 모듈화하여, 예외 발생 시 로그를 기록하도록 테이블을 만들어 관리
- 사용자 정의 예외는 별도 테이블을 만들어 관리