DATABASE(oracleDB 11g)/PLSQL

[PL/SQL]예외처리의 기초

SEUNGSAMI 2019. 2. 20. 11:10

예외처리의 기초


예시를 먼저 보도록 하자.


시작하기 앞서, 테이블에 제약조건을 추가하자.

1
2
ALTER TABLE emp
ADD CONSTRAINT emp_ck CHECK ( sal > 0 ) ;
cs



제약조건 때문에 다음의 구문은 ERROR가 발생한다.

1
2
3
UPDATE emp
SET sal = 0
WHERE empno = 7934 ;
cs



다음의 PL/SQL 블록은 비정상 종료가 이뤄진다.

1
2
3
4
5
6
7
8
9
10
11
BEGIN
  UPDATE emp
  SET sal = 3000
  WHERE empno = 7782 ;
 
  UPDATE emp
  SET sal = 0
  WHERE empno = 7934 ;
END ;
/
--블록 내에서 ERROR 발생시 블록 전체가 ROLLBACK된다.(비정상 종료)
cs



하지만 다음과 같이 예외처리를 해주면

1
2
3
4
5
6
7
8
9
10
11
12
13
14
BEGIN
  UPDATE emp
  SET sal = 3000
  WHERE empno = 7782 ;
 
  UPDATE emp
  SET sal = 0
  WHERE empno = 7934 ;
 
EXCEPTION
  WHEN OTHERS THEN
  DBMS_OUTPUT.PUT_LINE ( SQLERRM ) ;
END ;
/
cs

PL/SQL의 블록에서 에러가 발생한 지점에서 EXCEPTION절로 넘어가고 예외처리기를 통해 순차적으로 진행을 하고, 다시 돌아가지 않고, END로 빠져나간다.


그러면 예외를 알아보도록 하자.


예외란

블록 실행 중 에 발생한 PL/SQL 오류를 말한다.


예외는 세가지 유형으로 분류된다.

>암시적 예외

- 미리 정의된 Oracle 서버 오류

- 미리 정의되지 않은 Oracle 서버오류

>명시적 예외

- 유저 정의 오류



예외 트랩 구문은 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
EXCEPTION
    WHEN exception1 [OR exception2...] THEN
        statement1;
        statement2;
        ...
    [WHEN exception3 [OR exception4...] THEN
        statement1;
        statement2;
        ...]
    [WHEN OTHERS THEN
        statement1;
        statement2;
        ...]
cs


구문

설명

exception

예외의 이름

statement

하나 이상의 PL/SQL 또는 SQL문

OTHERS

명시적 처리되지않은 예외를 전부 선택



미리 정의되지 않은 오류 트랩의 경우

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
DECLARE
  emp_rec emp%ROWTYPE ;
  e_ck    EXCEPTION ;
  PRAGMA EXCEPTION_INIT (e_ck , -2290) ;
BEGIN
  SELECT * INTO emp_rec
  FROM emp
  WHERE ename = UPPER('&name') ;
 
  IF emp_rec.sal < 2000 THEN
    UPDATE emp
    SET sal = &salary
    WHERE empno = emp_rec.empno ;
  END IF ;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    DBMS_OUTPUT.PUT_LINE ('NO DATA') ;
  WHEN E_CK THEN
    DBMS_OUTPUT.PUT_LINE ('Invalid Salary') ;
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE (SQLERRM) ;
END ;
/
cs

다음과 같이 선언부에 예외 이름과, Oracle 서버 오류 코드를 트랩해야 한다.



예외 트랩에 대한 함수

함수

설명

SQLCODE

오류코드에 대한 숫자 값 반환

SQLERRM

오류번호와 연관된 메시지를 포함하는 문자 데이터를 반환



주의할 점으로는 EXCEPTION절이 없으면 비정상 종료이다.


유저 정의 예외 트랩

RAISE_APPLICATION_ERROR 프로시저

다음과 같은 구문을 사용한다.

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



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
BEGIN
 
  UPDATE emp
  SET sal = 3000
  WHERE empno = 7782 ;
  
  UPDATE dept
  SET dname = 'Testing'
  WHERE deptno = 50 ;
 
  IF SQL%NOTFOUND THEN
    RAISE_APPLICATION_ERROR ( -20001'No such department id.' ) ;
  END IF;
  
  UPDATE emp
  SET sal = 3000
  WHERE empno = 7566 ;
  
END;
/
cs

즉 위의 예시는 비정상 종료이고,


다음 예시는 에러가 나기 전까지 실행되고 정상종료된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
BEGIN
 
  UPDATE emp
  SET sal = 3000
  WHERE empno = 7782 ;
  
  UPDATE dept
  SET dname = 'Testing'
  WHERE deptno = 50 ;
 
  IF SQL%NOTFOUND THEN
    RAISE_APPLICATION_ERROR ( -20001'No such department id.' ) ;
  END IF;
  
  UPDATE emp
  SET sal = 3000
  WHERE empno = 7566 ;
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE(SQLERRM) ;
  
END;
/
cs



다음 서브 블록의 경우 비정상 종료가 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
BEGIN
  UPDATE emp
  SET sal = 7777
  WHERE empno = 7788 ;
 
  BEGIN
    UPDATE emp
    SET sal = 9999
    WHERE empno = 7566 ;
 
    UPDATE emp
    SET sal = 0
    WHERE empno = 7839 ;
 
    UPDATE emp
    SET sal = 9999
    WHERE empno = 7499 ;
  END ;
  
  UPDATE emp
  SET sal = 7777
  WHERE empno = 7369 ;
  
END ;
/
cs



추가로 중첩된 블록안에서 EXCEPTION절이 있는 경우

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
BEGIN
  UPDATE emp
  SET sal = 7777
  WHERE empno = 7788 ;
 
  BEGIN
    UPDATE emp
    SET sal = 9999
    WHERE empno = 7566 ;
 
    UPDATE emp
    SET sal = 0
    WHERE empno = 7839 ;
 
    UPDATE emp
    SET sal = 9999
    WHERE empno = 7499 ;
    
  EXCEPTION
    WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE (SQLERRM) ;    
  END ;
  
  UPDATE emp
  SET sal = 7777
  WHERE empno = 7369 ;
  
END ;
/
cs

중첩된 블록은 정상 종료되고, 밖의 블록이 정상적으로 진행된다.


그다음 중첩된 블록 밖에서 EXCETPION절이 있는 경우

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
BEGIN
  UPDATE emp
  SET sal = 7777
  WHERE empno = 7788 ;
 
  BEGIN
    UPDATE emp
    SET sal = 9999
    WHERE empno = 7566 ;
 
    UPDATE emp
    SET sal = 0
    WHERE empno = 7839 ;
 
    UPDATE emp
    SET sal = 9999
    WHERE empno = 7499 ;
    
  END ;
  
  UPDATE emp
  SET sal = 7777
  WHERE empno = 7369 ;
 
EXCEPTION
  WHEN OTHERS THEN
  DBMS_OUTPUT.PUT_LINE (SQLERRM) ;    
  
END ;
/
cs

이경우에는 첫번쨰 UPDATE만 살리고 나머지는 전부 종료된다.



SQL을 배운지 얼마 되지 않아 잘못된 내용이 있을 수 있습니다. 틀린 내용이있다면, 댓글로 달아주세요.