예외는 두가지로 나뉘는데 오라클에서 발생시키는 시스템예외와 사용자가 의도적으로 발생시키는 사용자 정의 예외로 나뉜다.
[예외 처리 구문]
EXCEPTION WHEN 예외명1 THEN 예외처리 구문1
WHEN 예외명2 THEN 예외처리 구문2
...
WHEN OTHERS THEN 예외처리구문n;
만약 예외처리 구문을 넣지 않고 프로시저를 실행하면 시스템에서 예외를 발생시켜 프로시저 실행을 중단하지만 사용자 정의 예외를 하게 되면 프로그램 제어권을 획들하여 여러 단계에 걸쳐 수행되는 프로그램의 정상동작을 보장할수 있지만 하지 않게 된 경우 프로그램의 흐름의 끊어져 버린다.
[SQLCODE,SQLERRM부분 정리]
SQLCODE : 실행부에서 발생한 예외에 해당하는 코드를 반환한다.
SQLERRM : 발생한 예외에 대한 오류메시지를 반환한다.
DBMS_UTILITY.FORMAT_ERROR_BACKTRACE : 몇번째 라인에서 에러가 발생했는지
[시스템 예외]
예외 처리시 OTHERS외에 시스템 예외명을 사용할수 있는데 이를 미리정의된 예외(predefined exception)라고 한다.
예외명 | 예외코드 | 설명 |
ACCESS_INTO_NULL | ORA-06530 | LOB과 같은 객체 초기화 되지 않은 상태에서 사용 |
CASE_NOT_FOUND | ORA-06592 | CASE문 사용시 구문오류 |
CURSOR_ALREADY_OPEN | ORA-06511 | 커서가 이미 OPEN된 상태인데 OPEN 시도 |
DUP_VAL_ON_INDEX | ORA-00001 | 유일인덱스가 있는 컬럼에 중복으로 INSERT,UPDATE |
INVALID_CURSOR | ORA-01001 | 존재하지 않는 커서 참조 |
INVALID_NUMBER | ORA-01722 | 문자를 숫자로 변환할때 실패 |
LOGIN_DENIED | ORA-01017 | 잘못된 사용자 이름이나 비밀번호 로그인시 |
NO_DATA_FOUND | ORA-01403 | SELECT INTO시 데이터 없을때 |
NO_LOGGED_ON | ORA-01012 | 로그온 되지 않은 상태에서 DB를 참조할때 |
PROGRAM_ERROR | ORA-06501 | PL/SQL코드상의 내부 오류를 만나면 Contact Oracle Suppot란 메시지가 출력 |
STORAGE_ERROR | ORA-06500 | 프로그램 수행시 메모리 부족 |
TIMEOUT_ON_RESOURCE | ORA-00051 | 데이터베이스 자원을 기다리는 동안 TIME OUT |
TOOMANY_ROWS | ORA-01422 | SELECT INTO 사용시 결과가 한 로우 이상일 경우 |
VALUE_ERROR | ORA-06502 | 수치 또는 값 오류 |
ZERO_DIVIDE | ORA-01476 | 0으로 나눌 경우 |
사용 방법은 아래 이미지와 같이 선언하여 사용하면 된다.
위의 그림과 같이 명시하여 처리한 후 명시된 부분에 대해 없을 경우 OTHERS로 처리를 하게 한다.
[사용자 예외]
아래 이미지와 같이 EX_INVALID_DEPID라는 사용자 정의 예외 부분을 선언하여 아래와 같이 처리를 했다.
예외처리 | 사용 방법 | 예시부분 |
사용자정의예외명 EXCEPTION | 변수나 상수처럼 PL/SQL블록의 선언부에 예외를 정의를 해야한다. |
EX_INVALID_DEPID EXCEPTION;
|
RAISE 사용자정의예외명; | 예외를 발생 시키려면 "RAISE 예외명"형태로 발생시켜야 한다. |
RAISE EX_INVALID_DEPID;
|
EXCEPTION WHEN 사용자정의예외명 THEN |
예외를 발생시키려면 시스템 예외와 동일한 방식으로 처리한다. |
EXCEPTION WHEN EX_INVALID_DEPID THEN
DBMS_OUTPUT.PUT_LINE('해당 부서번호가 없습니다'); |
※시스템 코드값으로 사용자 정의 예외 처리하기
아래 이미지와 같이
위의 이미지와 같이 EX_INVALID_DEPID라는 사용자 정의 예외 부분을 선언하여 아래와 같이 처리를 했다.
예외처리 | 사용 방법 | 예시부분 |
사용자정의예외명 EXCEPTION | 사용자정의예외를 선언부에서 선언한다. |
EX_INVALID_DEPID EXCEPTION;
EX_TEST_MONTH EXCEPTION; |
PARAGMA EXCEPTION_INTO (사용자정의예외명,시스템예외코드) |
PARAGMA EXCEPTION INIT를 사용하여 선언한 예외명과 시스템 예외코드를 명시한다. |
PRAGMA EXCEPTION_INIT
(EX_TEST_MONTH, -1843); |
ECEPTION WHEN 사용자정의예외명 THEN.......... | PARAGMA EXCEPTION에서 설정된 예외코드로 사용자정의예외명을 연결하여 실행. (요번건 월에서 범위가 벗어난 경우 -1843으로 코드가 나온다.) |
EXCEPTION WHEN EX_INVALID_DEPID THEN
DBMS_OUTPUT.PUT_LINE('해당 부서번호가 없습니다'); WHEN EX_TEST_MONTH THEN DBMS_OUTPUT.PUT_LINE(SQLCODE); DBMS_OUTPUT.PUT_LINE(SQLERRM); DBMS_OUTPUT.PUT_LINE('1~12월 범위를 벗어난 월입니다'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(SQLERRM); |
[RAISE_APPLICATION_ERROR프로시저 정리]
해당 RAISE_APPLICATION_ERROR프로시저는 DBMS_STANDARD시스템 패키지에 속한 프로시저로 사용자 정의 예외만 발생을 시킬수 있다. 예외코드와 원하는 예외 메시지를 직접 매개변수로 넘겨서 예외를 발생시키면 된다.
RAISE_APPLICATION_ERROR(예외코드,메시지);
여기서 중요한 점은 예외코드는 -20000 ~ -20999까지만 쓸수있다.(나머지는 오라클에서 쓰기 떄문에 못쓴다고함..해당 부분은 오라클에서 안쓴다고 한다.)
'DB > ORACLE' 카테고리의 다른 글
28.[오라클]커서 (0) | 2024.02.24 |
---|---|
27.[오라클]트랜잭션 (0) | 2024.02.24 |
25.[오라클]프로시저 정리 (0) | 2024.02.20 |
24.[오라클]PL/SQL 사용자 함수(FUNCTION) (5) | 2024.02.20 |
23.[오라클]PL/SQL제어문 정리 (0) | 2024.02.20 |