PL/SQL에서도 컴파일 에러 및 런타임 에러에 대해 예외 처리를 해주어야한다. 예외는 크게 시스템 예외와 사용자 정의 예외로 나눌 수 있다.
DECLARE
employee_record employees%ROWTYPE;
BEGIN
SELECT employee_id, last_name, department_id
INTO employee_record.employee_id,
employee_record.last_name,
employee_record.department_id
FROM employees
WHERE department_id = 50;
EXCEPTION -- 예외 처리부
--UNIQUE 제약을 갖는 컬럼에 중복된 데이터를 INSERT
WHEN DUP_VAL_ON_INDEX THEN
dbms_output.put_line('이미 존재하는 사원입니다.');
--SELECT문 결과가 2개 이상의 로우를 반환
WHEN TOO_MANY_ROWS THEN
dbms_output.put_line('검색 결과 로우가 너무 많습니다.');
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('검색된 사원이 없습니다.');
WHEN OTHERS THEN
dbms_output.put_line('기타 예외');
END;
DECLARE
e_user_exception EXCEPTION; --사용자 예외
cnt NUMBER := 0;
BEGIN
SELECT COUNT(*) INTO cnt
FROM employees
WHERE department_id = 40; -- 1명
IF cnt < 5 THEN
RAISE e_user_exception;
END IF
EXCEPTION
WHEN e_user_exception THEN
dbms_output.put_line('사원의 수가 너무 적습니다');
WHEN OTHERS THEN
dbms_output.put_line('정의되지 않은 예외입니다.');
END;
만약 시스템 예외에 예외명이 부여되지 않은 경우 아래와 같은 방법으로 예외명을 부여할 수 있다.
(예외명이 미리 정의된 것은 극소수이며 예외 코드만 존재하는 경우가 많다)
https://docs.oracle.com/cd/B28359_01/server.111/b28278/toc.htm
DECLARE
e_link_exception EXCEPTION;
PRAGMA EXCEPTION_INIT (e_link_exception, -1802);
CREATE TABLE error_log (
error_seq NUMBER, -- 에러 시퀀스
prog_name VARCHAR2(80), -- 프로그램명
error_code NUMBER, -- 에러코드
error_message VARCHAR2(300), -- 에러 메시지
error_line VARCHAR2(100), -- 에러 라인
error_date DATE DEFAULT SYSDATE -- 에러발생일자
);
CREATE TABLE app_user_define_error (
error_code NUMBER, -- 에러코드
error_message VARCHAR2(300), -- 에러 메시지
create_date DATE DEFAULT SYSDATE, -- 등록일자
PRIMARY KEY (error_code)
);