8. PL/SQL 예외처리

 

A. 예외란?

 

- SELECT 문이 행을 하나만 읽어 들일 것으로 예상했지만 여러 행을 읽어 오류 발생하며 블록이 종료됨

- 위와같이 런타임에 발생하는 오류를 예외라고 한다.

ex)

declare

  v_lname varchar2(15);

begin

  select last_name into v_lname

  from employees

  where first_name=‘John’;

  dbms_output.put_line (‘John’’s last name is : ‘ || v_lname);

exception

  when too_many_rows then

  dbms_output.put_line (‘ Your select statement retrleved multiple rows. Consider using a cursor. ‘);

end;

/

 

B. PL/SQL 예외 이해

§예외는 프로그램 실행 중에 발생한 PL/SQL 오류
§예외는 다음과 같이 발생
§Oracle 서버에서 묵시적으로 발생
§프로그램에 의해 명시적으로 발생
§예외를 다음과 같이 처리
§처리기로 트랩
§호출 환경으로 전달

 

C. 예외 유형

§묵시적으로 발생
§미리 정의된 Oracle 서버 오류
§미리 정의되지 않은 Oracle 서버 오류
§명시적으로 발생
§사용자 정의

 

D. 예외 트랩

§Syntax

EXCEPTION

  WHEN exception1 [OR exception2 …] THEN

  statement1;

  statement2;

 

  [WHEN exception3 [OR exception4 …] THEN

 

  [WHEN OTHERS THEN

  statement1;

  statement2;

  …] 

 

 E. 미리 정의된 Oracle 서버 오류

 

§미리 정의된 이름을 참조
§Sample
§NO_DATA_FOUND
§TOO_MANY_ROWS
§INVALID_CURSOR
§ZERO_DEVIDE
§DUP_VAL_ON_INDEX

 

F. 미리 정의되지 않은 Oracle 서버 오류 트랩

- 미리 정의되지 않은 예외는 표준 Oracle 오류.

- PRAGMA EXCEPTION_INIT 함수를 사용하여 표준 Oracle 오류가 있는 예외를 생성

ex)

declare

  e_insert_excep EXCEPTION;

  PRAGMA EXCEPTION_INIT(e_insert_excep, -01400);

begin

  insert into departments

  (department_id, department_name) values (280, NULL);

exception

  when e_insert_excep then

    dbms_output.put_line(‘INSERT OPERATION FAILED’);

    dbms_output.put_line(SQLERRM);

end;

/

 

G. 예외 트랩에 대한 함수

§SQLCODE : 오류 코드에 대한 숫자 값을 반환합니다.
§SQLERRM : 오류 번호와 연관된 메시지를 반환합니다.

ex)

DECLARE
error_code NUMBER;
error_message VARCHAR2(255);
BEGIN
...
EXCEPTION
...
WHEN OTHERS THEN
ROLLBACK;
error_code := SQLCODE ;
error_message := SQLERRM ;
INSERT INTO errors (e_user, e_date, error_code,
error_message) VALUES(USER,SYSDATE,error_code,
error_message);
END;
/

 

H. 유저 정의 예외 트랩

- 응용 프로그램의 요구사항에 따라 고유의 예외를 정의 가능

ex)

declare

  v_deptno number := 500;

  v_name varchar2(20) := ‘Testing’;

  e_invalid_dept exception;

begin

  update departments set department_name = v_name

  where department_id = v_deptno;

  if sql%notfound then

    raise e_invalid_dept;

  end if;

  commit;

exception

  when e_invalid_dept then

    dbms_output.put_line(‘No such department id.’);

end;

/

 

I. 서브 블록의 예외 전달

- 서브 블록은 예외를 처리하거나, 포함하는 블록으로 예외를 전달 할 수 있다.

DECLARE
    . . .
    e_no_rows exception;
    e_integrity exception;
    PRAGMA EXCEPTION_INIT (e_integrity, -2292);
BEGIN
    FOR c_record IN emp_cursor LOOP
        BEGIN
            SELECT ...
            UPDATE ...
            IF SQL%NOTFOUND THEN
                RAISE e_no_rows;
            END IF;
        END;
    END LOOP;
EXCEPTION
    WHEN e_integrity THEN ...
    WHEN e_no_rows THEN ...
END;
/

 

J. RAISE_APPLICATION_ERROR 프로시저

§Syntax

raise_application_error (error_number,

message[, {TRUE | FALSE} ] );

§error_number : 예외에 대한 유저 지정번호 (-20,000 ~ -20,999)
§message : 유저가 지정한 예외 메시지
§비표준 오류 코드 및 오류 메시지를 반환하여 미리 정의된 예외가 반환되지 않도록 할 수 있음.
§다음과 같은 위치에서 사용
§실행 섹션
§예외 섹션
§Oracle 서버 오류와 일치하는 방식으로 유저에게 오류 조건을 반환.

- 실행 섹션에서의 사용

BEGIN
...
    DELETE FROM employees
        WHERE manager_id = v_mgr;
    IF SQL%NOTFOUND THEN
        RAISE_APPLICATION_ERROR(-20202, 'This is not a valid manager');
    END IF;
...

- 예외 섹션에서의 사용

...
EXCEPTION
    WHEN NO_DATA_FOUND THEN
        RAISE_APPLICATION_ERROR (-20201, 'Manager is not a valid employee.');
END;
/

ex)

declare

  no_emp exception;

  pragma exception_init(no_emp, -20001);

begin

  delete from employees

  where employee_id = 9999;

  if sql%notfound then

    raise_application_error(-20001, ‘What!?!?!?!’);

  end if;

exception

  when no_emp then

    dbms_output.put_line(‘no data found’);

    dbms_output.put_line(sqlerrm);

end;

/

 

 

 

 

사업자 정보 표시
(주)블루원 | 김홍태 | 서울특별시 용산구 원효로 4가 135 금홍 2빌딩 | 사업자 등록번호 : 106-86-76684 | TEL : 02-3272-7200 | Mail : support_ora@blueone.co.kr | 통신판매신고번호 : 호 | 사이버몰의 이용약관 바로가기

+ Recent posts