오라클에서 사용자 정의 예외를 설정하는 것에 대해 알아봅시다. 사용자 정의 예외는 오라클 사전정의 예외 및 기타 예외 이외에 사용자가 직접 특정 예외를 지정하여 분기를 제어할 수 있도록 합니다.
사용자 정의 예외는 선언부에서 EXCEPTION 타입으로 변수를 선언하고, 발생을 원하는 지점에 RAISE문을 실행합니다.
예를 들면 다음의 예시에서 EMPNO가 '7839'인 사원이 존재하면 사원이 이미 존재한다는 사용자 정의 예외가 발생하도록 합니다. 예시는 익명블록으로 진행하였는데 보통은 펑션이나 프로시저에 예외를 추가할 것입니다.
"Exception occurs : the employee number already exists
PL/SQL procedure successfully completed."
SET SERVEROUTPUT ON;
DECLARE
cnt NUMBER;
ex_exists EXCEPTION;
BEGIN
SELECT COUNT (EMPNO)
INTO cnt
FROM EMP
WHERE EMPNO = '7839';
IF cnt > 0
THEN
RAISE ex_exists;
ELSE
DBMS_OUTPUT.PUT_LINE ('--todo');
END IF;
EXCEPTION
WHEN ex_exists
THEN
DBMS_OUTPUT.PUT_LINE (
'Exception occurs : the employee number already exists');
WHEN OTHERS
THEN
DBMS_OUTPUT.PUT_LINE (SQLCODE || ' ' || SQLERRM);
END;
오라클 미리 정의된 예외 (Predefined Exceptions)
오라클에서 미리 정의되어 굳이 사용자 정의를 할 필요 없는 예외 목록입니다. 오라클 버전 10g 기준입니다.
굳이 "ORA-00001 : 유일성 제약조건에 위배됩니다" 예외를 별도로 관리하기 위해 정의할 필요가 없는 것이지요.
EXCEPTION WHEN DUP_VAL_ON_INDEX THEN 과 같이 미리 정의된 코드로 사용할 수 있습니다.
사전 정의 예외 명칭 | 오라클 오류 코드 | SQLCODE |
ACCESS_INTO_NULL | ORA-06530 | -6530 |
CASE_NOT_FOUND | ORA-06592 | -6592 |
COLLECTION_IS_NULL | ORA-06531 | -6531 |
CURSOR_ALREADY_OPEN | ORA-06511 | -6511 |
DUP_VAL_ON_INDEX | ORA-00001 | -1 |
INVALID_CURSOR | ORA-01001 | -1001 |
INVALID_NUMBER | ORA-01722 | -1722 |
LOGIN_DENIED | ORA-01017 | -1017 |
NO_DATA_FOUND | ORA-01403 | +100 |
NOT_LOGGED_ON | ORA-01012 | -1012 |
PROGRAM_ERROR | ORA-06501 | -6501 |
ROWTYPE_MISMATCH | ORA-06504 | -6504 |
SELF_IS_NULL | ORA-30625 | -30625 |
STORAGE_ERROR | ORA-06500 | -6500 |
SUBSCRIPT_BEYOND_COUNT | ORA-06533 | -6533 |
SUBSCRIPT_OUTSIDE_LIMIT | ORA-06532 | -6532 |
SYS_INVALID_ROWID | ORA-01410 | -1410 |
TIMEOUT_ON_RESOURCE | ORA-00051 | -51 |
TOO_MANY_ROWS | ORA-01422 | -1422 |
VALUE_ERROR | ORA-06502 | -6502 |
ZERO_DIVIDE | ORA-01476 | -1476 |
RAISE_APPLICATION_ERROR
RAISE는 서브프로그램 자체에서 예외를 관리하려는 성격입니다. 그와 비교하여 RAISE_APPLICATION_ERROR는 서브프로그램에서 애플리케이션으로 예외코드 및 메시지를 전달하려고 사용합니다.
RAISE_APPLICATION_ERROR(error_number, message[, {TRUE | FALSE}]); 의 매개변수는 다음과 같습니다.
error_number : -20000에서 -20999까지 사용자가 지정할 수 있는 오류 번호
message : 오류에 관한 메시지
세 번째 매개변수는 기본값은 false인데, 예외를 스택으로 반환하느냐 덮어써서 반환하느냐를 결정합니다. 보통은 잘 사용하지 않습니다.
RAISE_APPLICATION_ERROR로 애플리케이션에 예외코드를 전달한 예시 자료입니다.
"ORA-20000: Exception occurs : the employee number already exists
ORA-06512: "USERNAME.FN_EX", 25행"
CREATE OR REPLACE FUNCTION FN_EX
RETURN VARCHAR2
IS
cnt NUMBER;
ex_exists EXCEPTION;
BEGIN
SELECT COUNT (EMPNO)
INTO cnt
FROM EMP
WHERE EMPNO = '7839';
IF cnt > 0
THEN
RAISE ex_exists;
ELSE
DBMS_OUTPUT.PUT_LINE ('--todo');
END IF;
RETURN '0';
EXCEPTION
WHEN ex_exists
THEN
raise_application_error (
-20000,
'Exception occurs : the employee number already exists');
WHEN OTHERS
THEN
DBMS_OUTPUT.PUT_LINE (SQLCODE || ' ' || SQLERRM);
END;