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 예외 이해
C. 예외 유형
D. 예외 트랩
EXCEPTION
WHEN exception1 [OR exception2 …] THEN
statement1;
statement2;
…
[WHEN exception3 [OR exception4 …] THEN
…
[WHEN OTHERS THEN
statement1;
statement2;
…]
E. 미리 정의된 Oracle 서버 오류
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. 예외 트랩에 대한 함수
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 프로시저
raise_application_error (error_number,
message[, {TRUE | FALSE} ] );
– 실행 섹션에서의 사용
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;
/