예외 사항 처리(런타임 오류)

PL/SQL 코드를 사용하여 런타임 시 발생하는 예외를 처리할 수 있습니다.

참조: PL/SQL 오류 처리에 대한 자세한 내용은 Oracle Database PL/SQL Language Reference를 참조하십시오

예외 사항 및 예외 사항 처리기

PL/SQL 코드에서 실행 시간 오류가 발생하면 예외가 발생합니다. 예외 사항이 발생한 하위 프로그램(또는 블록)에 예외 사항 처리 부분이 있으면 제어가 해당 부분으로 전송되고, 그렇지 않으면 실행이 정지됩니다.

런타임 오류는 디자인 결함, 코딩 실수, 하드웨어 장애 및 다른 많은 소스에서 발생할 수 있습니다.

Oracle Database에는 프로그램이 데이터베이스 규칙을 위반하거나 시스템 종속 제한을 초과할 때 자동으로 발생하는 미리 정의된 많은 예외 사항이 있습니다. 예를 들어, SELECT INTO 문에서 행을 반환하지 않는 경우 Oracle Database에서 미리 정의된 예외 NO_DATA_FOUND를 발생시킵니다. 미리 정의된 PL/SQL 예외 사항의 요약은 Oracle Database PL/SQL Language Reference를 참조하십시오.

PL/SQL을 사용하면 고유한 예외 사항을 정의(선언)할 수 있습니다. 예외 사항 선언의 구문은 다음과 같습니다.

exception_name EXCEPTION;

미리 정의된 예외 사항이나 달리 사용자 정의 예외 사항은 RAISE 문이나 DBMS_STANDARD.RAISE_APPLICATION_ERROR 프로시저를 사용하여 명시적으로 발생해야 합니다. 예:

IF condition THEN RAISE exception_name;

DBMS_STANDARD.RAISE_APPLICATION_ERROR 프로시저에 대한 자세한 내용은 Oracle Database PL/SQL Language Reference를 참고하십시오.

하위 프로그램의 예외 사항 처리 부분에는 예외 사항 처리기가 하나 이상 포함되어 있습니다. 예외 사항 처리기의 구문은 다음과 같습니다.

WHEN { exception_name [ OR exception_name ]... | OTHERS } THEN
  statement; [ statement; ]...

("하위 프로그램 구조 정보"는 서브 프로그램의 예외 처리 부분을 배치할 위치를 보여줍니다.)

WHEN OTHERS 예외 사항 처리기는 예기치 않은 실행 오류를 처리합니다. 사용하는 경우 마지막으로 사용해야 합니다. 예:

EXCEPTION
  WHEN exception_1 THEN
    statement; [ statement; ]...
  WHEN exception_2 OR exception_3 THEN
    statement; [ statement; ]...
  WHEN OTHERS THEN
    statement; [ statement; ]...
    RAISE;  -- Reraise the exception (very important).
END;

WHEN OTHERS 예외사항 처리기를 사용하는 대안은 EXCEPTION_INIT 프래그마이며, 이 프래그마는 사용자 정의 예외사항 이름을 Oracle Database 오류 번호와 연관시킵니다.

참조:

예외 처리기를 사용해야 하는 경우

다음 상황에서만 예외 처리기를 사용합니다.

미리 정의된 예외 사항 처리

미리 정의된 예외를 처리할 수 있습니다. 예 5-13에서는 미리 정의된 예외 사항 NO_DATA_FOUND를 처리하도록 EMP_EVAL.EVAL_DEPARTMENT 프로시저를 변경하는 방법을 보여 줍니다. 이 변경 작업을 수행하고 변경된 프로시저를 컴파일합니다. 패키지 본문을 변경하는 방법의 예제는 "자습서: 하위 프로그램에서 변수 및 상수 선언"을 참조하십시오.

예 5-13 사전 정의된 예외 처리 NO_DATA_FOUND

PROCEDURE eval_department(dept_id IN employees.department_id%TYPE) AS
  emp_cursor    emp_refcursor_type;
  current_dept  departments.department_id%TYPE;

BEGIN
  current_dept := dept_id;

  FOR loop_c IN 1..3 LOOP
    OPEN emp_cursor FOR
      SELECT *
      FROM employees
      WHERE current_dept = eval_department.dept_id;

    DBMS_OUTPUT.PUT_LINE
      ('Determining necessary evaluations in department #' ||
       current_dept);

    eval_loop_control(emp_cursor);

    DBMS_OUTPUT.PUT_LINE
      ('Processed ' || emp_cursor%ROWCOUNT || ' records.');

    CLOSE emp_cursor;
    current_dept := current_dept + 10;
  END LOOP;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    DBMS_OUTPUT.PUT_LINE ('The query did not return a result set');
END eval_department;

참조: Oracle Database PL/SQL Language Reference - 미리 정의된 예외에 대한 자세한 내용

사용자 정의 예외 사항 선언 및 처리

유저 정의 예외를 선언하고 처리할 수 있습니다. 예 5-14에서는 EMP_EVAL.CALCULATE_SCORE 함수를 변경하여 두 개의 사용자 정의 예외 사항 wrong_weight와 wrong_score를 선언 및 처리하는 방법을 보여 줍니다. 이 변경 작업을 수행하고 변경된 함수를 컴파일합니다. 패키지 본문을 변경하는 방법의 예제는 "자습서: 하위 프로그램에서 변수 및 상수 선언"을 참조하십시오.

예제 5-14 유저 정의 예외 처리

FUNCTION calculate_score ( evaluation_id IN scores.evaluation_id%TYPE
                         , performance_id IN scores.performance_id%TYPE )
                         RETURN NUMBER AS

  weight_wrong  EXCEPTION;
  score_wrong   EXCEPTION;
  n_score       scores.score%TYPE;
  n_weight      performance_parts.weight%TYPE;
  running_total NUMBER := 0;
  max_score     CONSTANT scores.score%TYPE := 9;
  max_weight    CONSTANT performance_parts.weight%TYPE:= 1;
BEGIN
  SELECT s.score INTO n_score
  FROM SCORES s
  WHERE evaluation_id = s.evaluation_id
  AND performance_id = s.performance_id;

  SELECT p.weight INTO n_weight
  FROM PERFORMANCE_PARTS p
  WHERE performance_id = p.performance_id;

  BEGIN
    IF (n_weight > max_weight) OR (n_weight < 0) THEN
      RAISE weight_wrong;
    END IF;
  END;

  BEGIN
    IF (n_score > max_score) OR (n_score < 0) THEN
      RAISE score_wrong;
   END IF;
 END;

  running_total := n_score * n_weight;
  RETURN running_total;

EXCEPTION
  WHEN weight_wrong THEN
    DBMS_OUTPUT.PUT_LINE(
      'The weight of a score must be between 0 and ' || max_weight);
    RETURN -1;
  WHEN score_wrong THEN
    DBMS_OUTPUT.PUT_LINE(
      'The score must be between 0 and ' || max_score);
    RETURN -1;
END calculate_score;

참조: Oracle Database PL/SQL Language Reference에서 사용자 정의 예외에 대한 자세한 내용을 참조하십시오.