본문 바로가기

Oracle/PLSQL Exception

PL/SQL Exception

Exception Handler를 선언한 경우 (0으로 나누기할때 발생하는 에러를 처리함)
.................................................................................................................................................................................................................

accept num_accept prompt '수 입력: ';
declare
  result number := 0;
  num number := &num_accept;
begin
 select 3/num into result from dual;
 dbms_output.put_line('3/'||num||'='||result);
 EXCEPTION
  WHEN zero_divide then
   dbms_output.put_line('0으로 수를 나누려고 해서 에러발생');
   --The optional OTHERS handler catches all exceptions that the block does not name specifically.
  WHEN OTHERS then
   dbms_output.put_line('에러발생');
end;
/

.................................................................................................................................................................................................................

EMP 테이블에서 사번으로 검색하여 검색결과가 없는 경우의 에러처리 예

accept empno prompt '사번 입력: ';
declare
  emp_no emp.empno%type := &empno;
  e_name emp.ename%type;
begin
 select ename into e_name from emp where empno=emp_no;
 dbms_output.put_line('사원검색결과: '||e_name);
 EXCEPTION
  WHEN no_data_found THEN
    dbms_output.put_line('검색결과 없음');
  WHEN others THEN
    dbms_output.put_line('검색중 에러발생');
end;
/

.................................................................................................................................................................................................................

개발자 정의 예외발생 및 처리 (회사내에 없는 부서번호를 입력한 경우)
user-defined exceptions must be declared and must be raised explicitly by RAISE statements.

accept deptno prompt '부서번호 입력: ';
declare
  dept_no emp.deptno%type := &deptno;
  cnt number := 0;
  no_such_dept EXCEPTION;
begin
 if(not dept_no IN(10,20,30)) then
   RAISE no_such_dept;
 end if;
 select count(*) into cnt from emp where deptno=dept_no;
 dbms_output.put_line('사원수: '||cnt);
 EXCEPTION
  WHEN no_such_dept THEN
   dbms_output.put_line('그런 부서번호는 없음');
  WHEN others THEN 
   dbms_output.put_line('검색중 에러발생');
end;
/

.................................................................................................................................................................................................................

PL/SQL에서 미리 정의된 이름이 있는 Exception 은  Exception Handler에서 처리하기가 쉽지만 오라클에서 발생하는 모든 에러에 이름이 붙여져 있는 것은 아니다. 그러므로 이름이 없는 Exception 을 처리하기 위해서는 위에서와 같이 OTHERS 를 사용하거나 혹은 Pragma EXCEPTION_INIT 를 사용해야 한다.

DECLARE
   deadlock_detected EXCEPTION;
   PRAGMA EXCEPTION_INIT(deadlock_detected, -60);
BEGIN
   ... -- Some operation that causes an ORA-00060 error
EXCEPTION
   WHEN deadlock_detected THEN
      -- handle the error
END;


.................................................................................................................................................................................................................

RAISE_APPLICATION_ERROR

아래와 같은 문장을 실행하면 ORA-xxxxx: message 형태의 오류 메시지가 출력된다.

SQL> select name from emp
                              *
1행에 오류:
ORA-00904: "NAME": 부적합한 식별자

개발자도 Stored Procedure(Function)를 작성할 때 아래와 같은 프로시저를 이용하면 위와 같은 시스템 오류 메시지를 출력할 수 있다.

raise_application_error(error_number, message[, {TRUE | FALSE}]);

파라미터 error_number : -20000 .. -20999 (음수로 표현해야 한다)
파라미터 emssage : character string up to 2048 bytes long


 
예제 (Stored Procedure나 Stored Function에서 사용할 수 있다)

CREATE PROCEDURE raise_salary (emp_id NUMBER, amount NUMBER) AS
   curr_sal NUMBER;
BEGIN
   SELECT sal INTO curr_sal FROM emp WHERE empno = emp_id;
   IF curr_sal IS NULL THEN
      /* Issue user-defined error message. */
      raise_application_error(-20101, 'Salary is missing');
   ELSE
      UPDATE emp SET sal = curr_sal + amount WHERE empno = emp_id;
   END IF;
END raise_salary;