[oracle] 오라클 PL/SQL - 예외 처리


오라클 PL/SQL - 예외 처리

8장. 예외 처리

예외 처리

Error

      - Syntax error
      - Logic  error
      - Runtime error -> Oracle-defined Exception -> Predefined exception      -> [1] when 이름 then
        (Exception)                               -> Non-predefined exception  -> [2] 선언 -> 이름부여 -> 자동 발생 -> 처리
                                                                                  [3] when others then
                      -> User_defined Exception                                -> [4] 선언 -> raise로 수동 발생 -> 처리
                                                                                  [5] raise_application_error 프로시져      
     
      - Every Oracle error has a number, but exceptions must be handled by name.

     - An exception raised in a declaration        propagates immediately to the enclosing block.
       An exception raised in an exception handler propagates immediately to the enclosing block.

     - https://scidb.tistory.com/entry/PLSQL-면접문제

Exception 처리 예제들

[1] when 이름 then (0) Predefined exception의 정체를 확인해 보세요

      1.파일을 여세요

        C:\Users\student> notepad c:\oraclexe\app\oracle\product\11.2.0\server\rdbms\admin\stdspec.sql
  
      2.다음으로 시작되는 파트를 찾으세요

        /********** Predefined exceptions **********/

(1) 발생한 Exception을 제대로 처리하지 못하는 경우

      drop table t1 purge;
      create table t1 (no number);
    
      create or replace procedure p1(a number, b number)
      is
      begin
        insert into t1 values(1000);
        p.p(a/b);
      end;
      /
    
      exec p1(100, 2)
    
      select * from t1;    -> 입력된 1000이 확인됨
    
      rollback;
    
      exec p1(100, 0)
    
      select * from t1;    -> no rows selected

(2) 발생한 Exception을 제대로 처리하는 경우


      create or replace procedure p1(a number, b number)
      is
      begin
        insert into t1 values(1000);
        p.p(a/b);
      exception
        when zero_divide then
          p.p('0으로 나눌 수 없습니다!');
        when others then
          p.p('에러 발생!');
      end;
      /
    
      exec p1(100, 0)
    
      select * from t1;  -> exception 발생 이전의 입력 데이터가 그대로 남아있음
    
      rollback;

[2] 선언 -> 이름부여 -> 자동 발생 -> 처리


      drop table t1 purge;
    
      create table t1 (no number not null);
    
      create or replace procedure p1(a number)
      is
        e_null exception;
        pragma exception_init(e_null, -1400);
      begin
        insert into t1 values(a);
      exception
        when e_null then
          p.p('null값 입력할 수 없습니다!');
      end;
      /
    
      exec p1(null)
      create or replace package exception_pack
      is
        e_null exception;
        pragma exception_init(e_null, -1400);
      end;
      /
    
      create or replace procedure p1(a number)
      is
      begin
        insert into t1 values(a);
      exception
        when exception_pack.e_null then
          p.p('null값 입력할 수 없습니다!');
      end;
      /
    
      exec p1(null)

[3] when others then

      create or replace procedure p1(a number)
      is
      begin
        p.p('다른 문장이 많음');
        insert into t1 values(a);
      exception
        when others then
          p.p(sqlcode);
          p.p(sqlerrm);
      end;
      /
    
      exec p1(null)

[4] 선언 -> raise로 수동 발생 -> 처리

      create or replace procedure p1(e number)
      is
        v_sal emp.sal%type;
        e_low exception;
      begin
        p.p('중요한 작업들');
    
        select sal into v_sal
        from emp
        where empno = e;
    
        if v_sal < 3000 then
          raise e_low;
        end if;
    
        p.p(v_sal);    
      exception
        when e_low then
          p.p('급여가 너무 적어요!');
      end;
      /
    
      exec p1(7788)
      exec p1(7900)

[5] raise_application_error 프로시져

      create or replace procedure p1(a number)
      is
        v_sal emp.sal%type;
      begin
        select sal into v_sal
        from emp
        where empno = a; 
    
        if v_sal < 3000 then
          raise_application_error(-20100, '급여가 너무 적어요!');
        end if;
      end;
      /
    
      exec p1(7900)    --exception처리 했지만 비정상 종료 됨
      create or replace procedure p1(a number)
        is
          v_sal emp.sal%type;
    
          e_too_low exception;
          pragma exception_init(e_too_low, -20100);
      begin
          select sal into v_sal
          from emp
          where empno = a; 
    
          if v_sal < 3000 then
            raise_application_error(-20100, '급여가 너무 적어요!');
          end if;
      exception
          when e_too_low then
            p.p('급여를 확인해 보세요!');
      end;
      /
    
      exec p1(7900)    
    cf. 트리거에서 에러가 발생하는 트리거를 유발한 작업이 실패한다

      - 첫번째 명령 프롬프트

      @KANG ~ $ sqlplus / as sysdba

      CREATE OR REPLACE TRIGGER ACE26_LOGON_TRI
      after LOGON ON ACE26.SCHEMA
      BEGIN
        IF SUBSTR(sys_context('USERENV', 'IP_ADDRESS'), 1, 9) in ('70.12.113', '70.12.114')  then
               RAISE_APPLICATION_ERROR ( -20002, 'IP '||ORA_CLIENT_IP_ADDRESS
                  || ' is not allowed to connect database!');
        END IF;
      END;
      /

      - 두번째 명령 프롬프트

      @KANG ~ $ sqlplus ace29/me@70.12.114.184:1521/xe

References

개발자님들 덕분에 많이 배울 수 있었습니다. 감사의 말씀 드립니다.





© 2020. GANGPRO. All rights reserved.