본문 바로가기

Database/Oracle

오라클 예외처리

 

//*****************************************
-- 예외처리
  - PL/SQL 을 실행 하는 동안에 발생하는 에러 처리

  - 예외 트랩(trap)
     만일 예외가 블록의 실행 가능한 섹션에서 발생한다면, 처리는 블록의 예외 섹션에서 해당 예외 처리기로 제어가 넘어 간다. PL/SQL 블록이 성공적으로 예외를 처리 한다면 이때 예외는 둘러싸는 블록이나 환경으로 전달 되지 않는다.

  -- 예외 전달
      예외를 처리하는 다른 방법은 실행 환경으로 예외를 전달하도록 하는 것이다. 예외가 블록의 실행부에서 발생하여 해당 예외 처리기가 없다면, PL/SQL 블록의 나머지 부분은 수행되지 못하고 종료된다.

  - 예외 검출
      예외가 블록의 실행부에서 발생하면 블록의 예외부에 있는 해당 예외 처리부로 제어가 넘어간다.

  - 예외의 유형
     실행 중에 ERROR가 발생하면 프로그램이 중단되지 않고 예외에 대한 프로그램을 할 수 있다.

    정의된 ORACLE SERVER ERROR : PL/SQL코드에서 자주 발생하는 ERROR을 미리 정의함(선언할 수 없고 ORACLE SERVER이 암시적으로 발생)
    정의되지 않은 ORACLE SERVER ERROR : 기타 표준 ORACLE SERVER ERROR(사용자가 선언하고 ORACLE SERVER이 그것을 암시적으로 발생)
   사용자 정의 ERROR : 프로그래머가 정한 조건이 만족되지 않을 경우 발생(사용자가 선언하고 명시적으로 발생한다.)

  - 예외정의
EXCEPTION
 WHEN  exception1 [OR exception2, . . . .] THEN
  statement1;
  statement2;
  . . . . . .
 [WHEN  exception2 [OR exception3, . . . .] THEN
  statement3;
  statement4;
  . . . . . .]
 [WHEN  OTHERS THEN
  statement5;
  statement6;
  . . . . . .]
END;

  OTHERS : 명시적으로 선언되지 않은 모든 예외를 트랩하는 예외 처리 절

//*****************************************
-- 정의돤 오라클 서버 에러
   NO_DATA_FOUND(ORA-01403) : 데이터를 RETURN하지 않는 SELECT문장
   TOO_MANY_ROWS(ORA-01422) : 단일 행 SELECT는 하나 이상의 행을 RETURN

----------------------------------------------------
DECLARE
    TYPE insa_rec IS RECORD (
        v_num insa.num%TYPE
        ,v_name insa.name%TYPE
        ,v_basicpay insa.basicpay%TYPE
    );
    rec insa_rec;
   
BEGIN
    SELECT num, name, basicpay INTO rec FROM INSA WHERE num=1001;
    -- SELECT num, name, basicpay INTO rec FROM INSA WHERE num=9001;
    -- SELECT num, name, basicpay INTO rec FROM INSA;
   
    IF rec.v_name = '홍길동' THEN
        UPDATE INSA SET name='김길동'  WHERE num=rec.v_num;
    END IF;
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        DBMS_OUTPUT.PUT_LINE('데이터가 없습니다.');
     WHEN TOO_MANY_ROWS THEN
        -- 단일행 SELECT문은 하나의 행만 리턴해야 한다.
        DBMS_OUTPUT.PUT_LINE('데이터가 여러개입니다.');  
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('기타 에러입니다.');
END;
/

SELECT * FROM INSA;
ROLLBACK;

SELECT * FROM INSA;


//*****************************************
-- 사용자 정의 예외
  -- 선언 절차
    1. 선언 섹션에서 사용자가 선언한다.
        exception_name EXCEPTION;

        exception_name : 예외 이름을 정의

    2. 실행 섹션에서 명시적으로 예외를 발생하기 위해 RAISE문장을 사용한다.
        RAISE exception_name;

        exception_name : 앞에서 선언된 예외 이름을 기술한다.

    3. 해당 예외 처리기 안에 선언된 예외를 참조한다.

----------------------------------------------------
DECLARE
    TYPE insa_rec IS RECORD (
        v_num insa.num%TYPE
        ,v_name insa.name%TYPE
        ,v_basicpay insa.basicpay%TYPE
    );
    rec insa_rec;
   
    insa_basicpay_check EXCEPTION;
   
BEGIN
    SELECT num, name, basicpay INTO rec FROM INSA WHERE num=1001;
    IF rec.v_basicpay > 2500000 THEN
        RAISE insa_basicpay_check;
    END IF;

    DBMS_OUTPUT.PUT_LINE(rec.v_name || '   ' || rec.v_basicpay);
EXCEPTION
    WHEN insa_basicpay_check THEN
        DBMS_OUTPUT.PUT_LINE('기본급이 250만원 이상입니다.');
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('기타 에러입니다.');
END;
/


//*****************************************
-- 예외 트래핑 함수
   에러가 발생 했을 때 두 함수를 사용하여 관련된 에러 코드 또는 메시지를 확인할 수 있다. 코드 또는 메시지에 따라 에러에 대해 취할 작업을 정할 수 있다.

  - SQLCODE : 에러코드
    0 : 에러 없이 정상적으로 실행되었음을 의미
    1 : 사용자가 정의한 에러가 발생했음을 의미
    +100 : 조건을 만족하는 행이 없음을 의미
    양수값 : 다른 오라클 에러가 발생했음을 의미
  - SQLERRM : 에러 메시지

----------------------------------------------------
DECLARE
    TYPE insa_rec IS RECORD (
        v_num insa.num%TYPE
        ,v_name insa.name%TYPE
        ,v_basicpay insa.basicpay%TYPE
    );
    rec insa_rec;
   
BEGIN
    SELECT num, name, basicpay INTO rec
                FROM INSA WHERE num=8001;
   
    IF rec.v_name = '홍길동' THEN
        UPDATE INSA SET name='김길동' WHERE num=rec.v_num;
    END IF;
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('에러 코드 : ' || SQLCODE);
        DBMS_OUTPUT.PUT_LINE('에러 메시지 : ' || SQLERRM);
END;
/


//*****************************************
-- RAISE_APPLICATION_ERROR
  - 형식
    RAISE_APPLICATION_ERROR(error_number, error_message);
    RAISE_APPLICATION_ERROR(error_number, error_message, keep_errors);
  - 표준화되지 않은 에러 코드와 에러 메시지를 리턴하기 위해 RAISE_APPLICATION_ERROR() 프로시져 사용
  - RAISE_APPLICATION_ERROR를 만나면 처리를 중단하며, 자바등의 어플리케이션에는 에러를 던져주어 어플리케이션에서는 SQLException을 이용해서 에러를 확인할 수가 있다.
  - error_message : 출력할 메시지
  - error_number : -20999~-20000사이의 수 사용
  - keep_errors : TRUE로 설정하면, stack 처럼 에러 리스트를 보존 가능하다. FALSE로 하면, 덮어쓰기를 한다. default로는 FALSE.

----------------------------------------------------
DECLARE
    v_num insa.num%TYPE;
BEGIN
    v_num := 8001;
    DELETE FROM insa WHERE num=v_num;
               
    IF SQL%NOTFOUND THEN
        RAISE_APPLICATION_ERROR(-20100, '자료가 없음');
    END IF;
END;
/

 

'Database > Oracle' 카테고리의 다른 글

오라클 테이블스페이스(수정중)  (0) 2014.11.21
오라클 패키지  (0) 2014.11.21
오라클 트리거(TRIGGER)  (0) 2014.11.21
오라클 커서와 동적SQL  (0) 2014.11.21
오라클 사용자 정의 함수(FUNCTION)  (0) 2014.11.21