Oracle PL/SQL 강좌
미리 정의된 예외(Predefined Exceptions) 9 9 99,999+

by 구루비 미리 정의된 예외 NO_DATA_FOUND TOO_MANY_ROWS INVALID_CURSOR ZERO_DIVIDE DUP_VAL_ON_INDEX EXCEPTION [2002.01.20]


오라클 PL/SQL은 자주 일어나는 몇가지 예외를 미리 정의해 놓았으며, 이러한 예외는 개발자가 따로 선언할 필요가 없다.

미리 정의된 예외의 종류

  - NO_DATA_FOUND : SELECT문이 아무런 데이터 행을 반환하지 못할 때

  - DUP_VAL_ON_INDEX : UNIQUE 제약을 갖는 컬럼에 중복되는 데이터가 INSERT 될 때

  - ZERO_DIVIDE : 0으로 나눌 때

  - INVALID_CURSOR : 잘못된 커서 연산

  - Predefined PL/SQL Exceptions 더 보기

미리 정의된 예외 예제

 
SQL> CREATE OR REPLACE PROCEDURE PreException_test
         (v_deptno  IN emp.deptno%TYPE)  
    
   IS

       v_emp   emp%ROWTYPE;

   BEGIN

      DBMS_OUTPUT.ENABLE;

      SELECT empno, ename, deptno
      INTO v_emp.empno, v_emp.ename, v_emp.deptno
      FROM emp
      WHERE deptno = v_deptno ;

      DBMS_OUTPUT.PUT_LINE('사번 : ' || v_emp.empno);
      DBMS_OUTPUT.PUT_LINE('이름 : ' || v_emp.ename);
      DBMS_OUTPUT.PUT_LINE('부서번호 : ' || v_emp.deptno);

   EXCEPTION

      WHEN   DUP_VAL_ON_INDEX   THEN
    
          DBMS_OUTPUT.PUT_LINE('데이터가 존재 합니다.');
          DBMS_OUTPUT.PUT_LINE('DUP_VAL_ON_INDEX 에러 발생');

      WHEN   TOO_MANY_ROWS   THEN  

        DBMS_OUTPUT.PUT_LINE('TOO_MANY_ROWS에러 발생');

      WHEN   NO_DATA_FOUND   THEN  

        DBMS_OUTPUT.PUT_LINE('NO_DATA_FOUND에러 발생');

      WHEN OTHERS THEN 

        DBMS_OUTPUT.PUT_LINE('기타 에러 발생');

  END;
  / 

-- DBMS_OUTPUT.PUT_LINE을 출력하기 위해 사용
SQL> SET SERVEROUTPUT ON ;  

-- 프로시저 실행
SQL> EXECUTE PreException_Test(20);
TOO_MANY_ROWS에러 발생

-- TOO_MANY_ROWS 에러가 발생하는 이유?
 - SELECT문의 결과가 1개 이상의 행을 리턴하기 때문이다..
 - TOO_MANY_ROWS를 피하기 위해서는 FOR문이나 LOOP문으로 SELECT문을 처리해야 한다.

--아래와 같이 변경하면 에러가 발생하지 않는다.

  FOR  emp_list  IN
      (SELECT empno, ename, deptno
       FROM emp
       WHERE deptno = v_deptno)   LOOP

      DBMS_OUTPUT.PUT_LINE('사번 : ' || emp_list.empno);
      DBMS_OUTPUT.PUT_LINE('이름 : ' || emp_list.ename);
      DBMS_OUTPUT.PUT_LINE('부서번호 : ' || emp_list.deptno);

  END LOOP;
    

- 강좌 URL : http://www.gurubee.net/lecture/1071

- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^

- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.

by 초보자 [2005.12.21 16:19:33]
(v_deptno IN emp.empno%TYPE) 에서 변수의 데이터 타입이 틀린거 아닌가여?
(v_deptno IN emp.deptno%TYPE) 로 바뀌어야 하는거 아닌가여?

by darkturtle [2006.01.17 19:01:57]
초보자 님이 맞네요..
empno number(4)
deptno number(2) 인 상황이라 에러는 발새 하지 않고,
로직상 부서 정보를 입력하는것이니 초보자님이 맞는것으로보입니다.

by 디스타임 [2007.11.09 17:05:27]
데이터타입유형만 가져오는 것이니 틀린게 아니져. 전혀 연관성 없는 거니..

by 김윤경 [2007.11.12 17:22:52]
데이타 타입만 맞으면 상관 없다고 봅니다.

by 나그네 [2007.12.31 11:59:42]
잠재적 에러를 내포하고 있군요. %TYPE을 쓰는 이유가 테이블에 레코드 타입이 바뀌어도 프로시져를 변경 안해도 되는건데....

by 최세민 [2008.06.11 02:04:53]
마지막 WHEN 에 OTHERS THEN 가 생략 되었습니다.
WHEN OTHERS THEN 가 맞을듯 하네요

by Shong [2009.11.16 15:45:39]
WHEN DBMS_OUTPUT.PUT_LINE(’기타 에러 발생’);
으로 해도 되나요??
저는 WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(’기타 에러 발생’);
으로 했었는데요. 같은게 되나??

by 디비벨리 [2012.01.27 11:53:37]
WHEN DBMS_OUTPUT.PUT_LINE(’기타 에러 발생’);
안되지 않나요 ?

by 하나아린 [2019.03.26 10:22:24]

프로시저 실행에 

SQL> EXECUTE PreException_Test(20)

이렇게 되어있는데 위의 프로시저에는 PreException_test 이렇게 적혀있어요. 대소문자가 구분 되는건가요...?

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입