예외 상황 처리(PL/SQL)
기본적으로 PL/SQL 프로그램에서 발생한 오류는 프로그램 실행을 중지합니다. EXCEPTION 섹션을 사용하여 오류를 트랩하고 복구할 수 있습니다.
예외 상황 처리기(exception handler) 구문은 BEGIN 블록 구문의 확장입니다.
구문
.---------------. V | >>-+--------------------------+--BEGIN----+-----------+-+-------> | .-------------. | '-statement-' | V | | '-DECLARE----declaration-+-' >--+------------------------------------------------------------------------------------------+--> | .-------------------. .-------------------. | | V | V | | '-EXCEPTION--WHEN--exception-condition----+---------------+-+--THEN----handler-statement-+-' '-OR--condition-' >--END---------------------------------------------------------><
오류가 발생하지 않은 경우 블록은 단순히 statement를 실행하고 END 다음의 명령문으로 제어가 전달됩니다. 그러나 statement 실행 중 오류가 발생한 경우 statement 처리가 중단되고 EXCEPTION 섹션으로 제어가 전달됩니다. WHEN절에서 발생한 오류와 일치하는 첫 번째 예외를 검색합니다. 일치하는 항목이 있으면 대응하는 handler-statement가 실행되고 END 다음의 명령문으로 제어가 전달됩니다. 일치하는 항목이 없으면 프로그램 실행이 중지됩니다.
handler-statement 실행 중에 새 오류가 발생하는 경우에는 주위의 EXCEPTION절에 의해서만 오류가 예외 처리(catch)될 수 있습니다.
WHEN절의 예외는 사용자 정의 예외이거나 내장 예외입니다. 사용자 정의 예외는 현재 블록 또는 주변 블록의 DECLARE 섹션이나 PL/SQL 패키지의 DECLARE 섹션에 정의할 수 있습니다. 예외 정의 바로 뒤에 PRAGMA EXCEPTION_INIT 또는 PRAGMA DB2_EXCEPTION_INIT 구문을 사용하여 사용자 정의 예외에 대응하는 sqlcode 또는 sqlstate를 지정할 수 있습니다.
- exception1은 sqlcode 또는 sqlstate와 연관되어 있지 않습니다.
- exception2는 sqlcode -942(정의되지 않은 이름)와 연관되어 있습니다.
- exception3은 sqlstate 42601(구문 오류)과 연관되어 있습니다.
DECLARE
exception1 EXCEPTION;
exception2 EXCEPTION;
PRAGMA EXCEPTION_INIT(exception2,-942);
exception3 EXCEPTION;
PRAGMA DB2_EXCEPTION_INIT(exception3,'42601');
BEGIN
MyApp.Main(100);
EXCEPTION
WHEN exception1 THEN
DBMS_OUTPUT.PUT_LINE('User-defined exception1 caught');
WHEN exception2 THEN
DBMS_OUTPUT.PUT_LINE('User-defined exception2 (Undefined name) caught');
WHEN exception3 THEN
DBMS_OUTPUT.PUT_LINE('User-defined exception3 (Syntax error) caught');
END
PRAGMA EXCEPTION_INIT로 초기화된 예외가 예외 처리(catch)된 경우, SQLCODE 함수가 리턴하는 값은 Oracle 값이 아니라 예외와 연관된 sqlcode입니다. 앞의 예에서 exception2가 예외 처리(catch)되는 경우, SQLCODE가 리턴하는 값은 Oracle sqlcode -942에 대응하는 sqlcode인 -204입니다. PRAGMA EXCEPTION_INIT에 지정된 Oracle sqlcode가 Oracle- 오류 맵핑 테이블에 나열되어 있지 않는 경우에는 컴파일에 실패합니다. PRAGMA EXCEPTION_INIT를 PRAGMA DB2_EXCEPTION_INIT로 대체하고 식별하려는 오류에 대응하는 sqlstate를 지정하면 이를 방지할 수 있습니다.
| 예외 이름 | 설명 |
|---|---|
| CASE_NOT_FOUND | CASE문에 있는 어느 케이스도 "true"로 평가되지 않으며, ELSE 조건이 없습니다. |
| CURSOR_ALREADY_OPEN | 이미 열린 커서를 열려고 했습니다. |
| DUP_VAL_ON_INDEX | 인덱스 키에 대한 중복 값이 있습니다. |
| INVALID_CURSOR | 열리지 않은 커서에 액세스하려고 했습니다. |
| INVALID_NUMBER | 숫자 값이 유효하지 않습니다. |
| LOGIN_DENIED | 사용자 이름 또는 암호가 유효하지 않습니다. |
| NO_DATA_FOUND | 선택 기준을 만족시키는 행이 없습니다. |
| NOT_LOGGED_ON | 데이터베이스 연결이 없습니다. |
| OTHERS | 예외 섹션에서 이전 조건에 의해 예외 처리(catch)되지 않은 예외에 해당합니다. |
| SUBSCRIPT_BEYOND_COUNT | 배열 인덱스가 범위를 벗어났거나 존재하지 않습니다. |
| SUBSCRIPT_OUTSIDE_LIMIT | 배열 인덱스 표현식의 데이터 유형을 배열 인덱스 유형에 지정할 수 없습니다. |
| TOO_MANY_ROWS | 선택 기준을 만족시키는 행이 둘 이상 있지만 하나의 행만 리턴할 수 있습니다. |
| VALUE_ERROR | 값이 유효하지 않습니다. |
| ZERO_DIVIDE | 0으로 나누려고 했습니다. |
