5장. ORACLE EXCEPTION(예외처리)

 

1. PL/SQL 예외란?

 : pl/sql블록이 parse되는 동안 오타로 인해 발생되는 에러를 컴파일에러라고 부르고,

pl/sql블록이 실행되는 동안 발생되는 에러가 런타임 에러라고 부르는데, 오라클에서는 이를 예외(exception)이라고 부른다.

 

* 오라클의 예외종류

① oracle exceptionl (오라클 예외)

② User-defined Exception (사용자 정의 예외)   (ex.과장급 아래인 일반사원이 조회하면 '권한이 없습니다.'와 같은 에러를 띄우는 것.)

 

* 미리 정의되어 있는 주요 오라클 예외 (참고만 할 것.)

예외명: ACCESS_INTO_NULL      
예외번호: ORA-06530
설명: 정의되지 않은 오브젝트 속성에 값을 할당하고자 했을 때 발생되는 예외.

예외명: CASE_NOT_FOUND       
예외번호: ORA-06592
설명: CASE 문의 WHEN 절에 해당되는 조건이 없고  ELSE 절도 없을 경우에 발생되는 예외.

예외명: COLLECTION_IS_NULL       
예외번호: ORA-06531
설명: 선언되지 않은 컬렉션  (nested table, varray)에  EXISTS 이외의 메소드를 사용했을 때 발생되는 예외.

예외명: CURSOR_ALREADY_OPEN      
예외번호: ORA-06511
설명: 이미 열려진 커서를 열려고 시도 했을 때 발생되는 예외.

예외명: DUP_VAL_ON_INDEX        
예외번호: ORA-00001
설명: 유일인덱스에 중복값을 입력했을 경우 발생되는 예외.

예외명: INVALID_CURSOR        
예외번호: ORA-01001
설명: 잘못된 커서 조작이 실행될 때 발생되는 예외.

예외명: INVALID_NUMBER       
예외번호: ORA-01722
설명: 문자를 숫자로의 변환 시 실패가 될 때 발생되는 예외.

예외명: LOGIN_DENIED      
예외번호: ORA-01017
설명: 잘못된 사용자명 이나 암호로 로그인을 시도했을 때 발생되는 예외.

예외명: NO_DATA_FOUND          
예외번호: ORA-01403
설명: PL/SQL SELECT문이 한 건도 리턴 하지 못했을 경우 발생하는 예외

예외명: NOT_LOGGED_ON        
예외번호: ORA-01012
설명: 접속되지 않은 상태에서 데이터베이스에 대한 요청이  PL/SQL 프로그램으로 실행된 경우 발생되는 예외.

예외명: PROGRAM_ERROR        
예외번호: ORA-06501
설명: PL/SQL 이 내부적인 문제를 가지고 있는 경우 발생되는 예외

예외명: ROWTYPE_MISMATCH         
예외번호: ORA-06504
설명: 할당문에서 호스트 커서 변수와  PL/SQL 커서 변수의 데이터 형이 불일치 할 때 발생되는 예외

예외명: STORAGE_ERROR        
예외번호: ORA-06500
설명: PL/SQL 이 실행될 때 메모리가 부족하거나 메모리상에 문제가 일어났을 때 발생하는 예외

예외명: SUBSCRIPT_BEYOND_COUNT        
예외번호: ORA-06533
설명: 컬렉션의 요소 개수보다 더 큰 첨자 값으로 참조한 경우 발생되는 예외.

예외명: SUBSCRIPT_OUTSIDE_LIMIT         
예외번호: ORA-06532
설명: 컬렉션의 첨자의 한계를 벗어난 참조가 일어났을 때 발생되는 예외

예외명: SYS_INVALID_ROWID        
예외번호: ORA-01410
설명: 문자열을 ROWID 로 변환할 때 무효한 문자열의 표현일 경우 발생되는 예외

예외명: TIMEOUT_ON_RESOURCE        
예외번호: ORA-00051
설명: 자원에 대한 대기시간이 초과했을 때 발생하는 예외

예외명: TOO_MANY_ROWS        
예외번호: ORA-01422
설명: PL/SQL SELECT문이 두 건 이상의 행을 리턴 했을 때 발생되는 예외

예외명: ZERO_DIVIDE        
예외번호: ORA-01476
설명: 0으로 나누려 했을 때 발생하는 예외.

 

 

 

2. 예외 처리 사용하기

 

[문  법]

 
EXCEPTION
WHEN exception1 [OR exception2 …] THEN
     statement1 ;
     statement2 ;

[ WHEN exception3 [OR exception4 …] THEN
     statement3 ;
     statement4 ;
… ]
[WHEN OTHERS THEN
     statementN ;
     statementN+1 ;
… ]  

 

- OTHERS : 이전의 WHEN 에 해당되지 않는 예외들은 모두 이 OTHERS 예외에서 처리.
 


 [예외처리 사용 예  1: 오라클에서 사전 정의된 예외 사용하기 ]
사원명이  ‘A’ 로 시작하는 사원을 조회하여 묵시적 커서를 사용하여 출력하되 여러 건의 데이터가 나올 경우 에러를 발생시키는 예외 처리를 생성합니다.

 

SQL> SELECTename
   2   FROM emp
   3  WHERE ename LIKE 'A%';
 
ENAME
--------------------
ALLEN
ADAMS   -- A 로 시작하는 사원이  2명 검색됩니다.

 
이 사원들의 이름을 출력하는  PL/SQL 을 작성하는데 데이터가  2건 이므로 명시적 커서를 사용해야 하지만 묵시적 커서를 사용하여

TOO_MANY_ROWS 라는 예외가 발생한다.

 


 

SQL> DECLARE
   2    v_ename   emp.ename%TYPE;
   3  BEGIN
   4     SELECT ename    INTO v_ename
   5     FROM emp
   6    WHERE ename    LIKE 'A%';
   7    DBMS_OUTPUT.PUT_LINE ('사원명은' ||v_ename||' 입니다');
   8   EXCEPTION    -- 이 에러를 쓰지 않으면 오라클이 미리 정해놓은 에러인 Too_many_rows를 띄운다.
   9     WHEN NO_DATA_FOUND   THEN
 10      DBMS_OUTPUT.PUT_LINE(' 해당 사원이 없습니다');
 11    WHEN TOO_MANY_ROWS  THEN
 12      DBMS_OUTPUT.PUT_LINE(' 사원이 두 명 이상입니다');

  13    END;
  14   /  

 

 

 

[예외처리 사용 예  2. PRAGMA 를 사용하여 에러메시지 변경하기]

 : pragma란?  특정 에러코드를 예외 메시지로 바꿔주는 역할.

 

두 개의 테이블이 서로  Foreign Key 가 설정되어 있는 상태에서 부모테이블에서 부서번호를  입력  받아  해당  부서를  삭제하되  자식  테이블에  해당  부서에  소속된  사원이  있을  경우 ‘ 해당 부서에 사원이 존재하므로 삭제할 수 없습니다’ 라는 예외를 발생시키는 예제.

 

SQL> DECLARE
   2    sawon_exist   EXCEPTION;
   3     PRAGMA   EXCEPTION_INIT(sawon_exist,-2292);   --2292에러코드가 뜨면 sawon_exist 메시지를 실행한다.  
   4  BEGIN
   5    DELETE FROM dept
   6    WHERE deptno =&dno;
   7    COMMIT;
   8   EXCEPTION
   9    WHEN sawon_exist THEN
 10    DBMS_OUTPUT.PUT_LINE('해당 부서에 사원이 존재하므로 삭제할 수 없습니다');
  11    END ;
  12     /
Enter value for dno: 10
해당 부서에 사원이 존재하므로 삭제할 수 없습니다  

 

 

 

no 컬럼에  PRIMARY KEY 를  설정해서 중복되는 값과  NULL 값이 입력되지 않도록 설정 한 후 일부러 중복되는 값을 입력해서 ORA-00001 번 에러를 발생시키는 예제.

 

SCOTT>CREATE TABLE t_pragma
   2  (no      NUMBER   PRIMARY KEY ,
   3   name   VARCHAR2(10)); 

Table created.
 
SCOTT>INSERT INTO t_pragma
   2  VALUES(1,'AAA') ;
 
1 row created.
 
SCOTT>INSERT INTO t_pragma
   2  VALUES(1,'BBB');
INSERT INTO t_pragma
*
ERROR at line 1:
ORA-00001: unique constraint (SCOTT.SYS_C0013626) violated --NO컬럼이 Primary key 이므로 중복된 데이터가 들어갈 수 없어서.

 

 


 

 

SCOTT> DECLARE
  2    new_msg  EXCEPTION;
  3    PRAGMA EXCEPTION_INIT(new_msg, -1);  
--1번 에러 발생하면 new_msg에러메시지 호출해라.
   4  BEGIN
   5    INSERT INTO t_pragma
   6    VALUES(1,'CCC');
  7  EXCEPTION
  8    WHEN new_msg   THEN
  9     DBMS_OUTPUT.PUT_LINE('이미 존재하는 번호입니다!');
  10    END ;
  11   /  

 

 

 

NOT NULL 제약 조건이 설정되어 있는 컬럼에 NULL 값을 입력해서 ORA-01400 에러를 발생.

 

SCOTT>CREATE TABLE t_con 
2  ( no       NUMBER NOT NULL ,
3   name    VARCHAR2(10)); 


Table created.
 
SCOTT>INSERT INTO t_con
   2  VALUES(1,'AAA');
 
1 row created.
 
SCOTT>INSERT INTO t_con
   2  VALUES(null,'BBB');
VALUES(null,'BBB')
        *
ERROR at line 2:
ORA-01400: cannot insert NULL into ("SCOTT"."T_CON"."NO")  --no칼럼에 not null 제약조건이 걸려 있는데, null값 입력해서 에러발생
 
SCOTT>DECLARE
   2  new_msg  EXCEPTION;
   3  PRAGMA EXCEPTION_INIT(new_msg, -1400); 

   4
   5  BEGIN
   6   INSERT INTO t_con
   7    VALUES(null,'BBB');
   8                                      
   9  EXCEPTION
 10    WHEN new_msg   THEN
 11      DBMS_OUTPUT.PUT_LINE('null 값은 입력할 수 없습니다');
  12   END;
  13  /
 
null 값은 입력할 수 없습니다
PL/SQL procedure successfully completed.

 

 

 

 

* 특정 상황이 되면 예외처리를 하는 경우들은 RAISE 나 RAISE_APPLICATION_ERROR 프로시저를 사용한다. 


[ 예외 처리 사용 예  3: RAISE 를 사용하여 예외 상황 처리하기 ]
 
empno 를 입력 받은 후  emp 테이블에서 해당 사원을 지우는 작업을 수행합니다. 단, 없는 사원번호를 입력할 경우  ‘사원이 없습니다’ 라는 예외 메시지를 출력. 

 

SCOTT>DECLARE
   2         no_empno  EXCEPTION ;
   3  BEGIN
   4      DELETE FROM EMP
   5      WHERE empno =&empno;
   6       IF SQL%NOTFOUND   THEN
   7         RAISE no_empno ; 
   8       END IF; 
  9   EXCEPTION
 10      WHEN no_empno THEN
 11         DBMS_OUTPUT.PUT_LINE('조회한 사번의 사원은 없습니다');
  12   END ;
  13   /
 
Enter value for empno: 7901
조회한 사번의 사원은 없습니다 

 

 

[예외 처리 사용 예  4 : RAISE_APPLICATION_ERROR 프로시저 사용하기 ]

 

RAISE_APPLICATION_ERROR 프로시저란? : 사용자가 특정 상황에 발생할 에러를 정의하고 예외 처리부를 사용하지 않고, 실행부에서 즉시 예외를 처리하는 방식. -> 에러 코드번호를 사용자가 직접 지정해서 출력할 수 있는데 이때 사용자가 임의로 지정이 가능한 에러 번호는  20000 번부터  20999 번 까지이다.

 

 

SCOTT>SET VERIFY OFF
SCOTT>BEGIN
   2  DELETE FROM emp WHERE empno=&empno ;
   3     IF   SQL%NOTFOUND   THEN
   4       RAISE_APPLICATION_ERROR(-20001,'존재하지 않는 사번입니다');
   5     END IF;
   6   END ;
   7  /
Enter value for empno: 7901
BEGIN
*
ERROR at line 1:
ORA-20001: 존재하지 않는 사번입니다
ORA-06512: at line 4

 

 

 

[ 예외처리 사용 예 5: SQLCODE 와  SQLERRM 사용하기] 
* 에러 내역 확인 : SQLCODE , SQLERRM

모든 예외를 일일이 예외 처리부에 다 기록할 수 없기 때문에  SQLCODE 와  SQLERRM을 사용하여 에러를 찾아서 보여주는 경우도 많이 있다.

 

사용자로부터  empno 를  입력  받아서  해당  empno  의  ename  을 화면에 출력하는 코드. 이 때, 존재하지 않는 empno 를 입력할 경우 발생하는 Error code 와  Error 내용을 확인. 

 

SCOTT>SET VERIFY OFF
SCOTT>DECLARE
   2     name      emp.ename%TYPE;
   3     v_code    NUMBER;
   4     v_errm    VARCHAR2(64);
   5    BEGIN
   6      SELECT ename INTO name FROM emp WHERE empno = &eno;
   7      EXCEPTION
   8      WHEN OTHERS THEN
   9         v_code := SQLCODE;
  10        v_errm := SUBSTR(SQLERRM, 1 , 64);
  11         DBMS_OUTPUT.PUT_LINE('The error code is ' || v_code || '- ' || v_errm);
  12   END ;
  13  /
Enter value for eno: 7902 
PL/SQL procedure successfully completed. <-- 존재하는  empno 라서 에러 없습니다.

 

SCOTT>/
Enter value for eno: 7900
The error code is 100- ORA-01403: no data found  <-- 존재하지 않는 번호라서 에러 발생합니다. 

 

 

 

'[기타SQL] > PL_SQL' 카테고리의 다른 글

6. Oracle Subprogram ★★★  (0) 2014.10.16
4. PL/SQL Cursor(커서) 정리해야됨.  (1) 2014.10.14
3. PL/SQL 제어문.  (0) 2014.10.13
2. PL/SQL 변수.  (0) 2014.10.13
1. ORACLE PL/SQL 시작하기  (0) 2014.10.13
Print Friendly and PDF Posted by JJ*
: