예외 사항 처리(런타임 오류)
PL/SQL 코드를 사용하여 런타임 시 발생하는 예외를 처리할 수 있습니다.
참조: PL/SQL 오류 처리에 대한 자세한 내용은 Oracle AI Database PL/SQL Language Reference를 참조하십시오.
예외 사항 및 예외 사항 처리기
PL/SQL 코드에서 실행 시간 오류가 발생하면 예외가 발생합니다. 예외 사항이 발생한 하위 프로그램(또는 블록)에 예외 사항 처리 부분이 있으면 제어가 해당 부분으로 전송되고, 그렇지 않으면 실행이 정지됩니다.
런타임 오류는 디자인 결함, 코딩 실수, 하드웨어 장애 및 다른 많은 소스에서 발생할 수 있습니다.
Oracle AI Database에는 프로그램이 데이터베이스 규칙을 위반하거나 시스템 종속 제한을 초과할 때 자동으로 발생하는 미리 정의된 많은 예외 사항이 있습니다. 예를 들어, SELECT INTO 문에서 행을 반환하지 않는 경우 Oracle AI Database에서 미리 정의된 예외 NO_DATA_FOUND를 발생시킵니다. 미리 정의된 PL/SQL 예외 사항의 요약은 Oracle AI 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 AI 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 예외사항 처리기를 사용하는 경우 대신 사용자 정의 예외사항 이름을 Oracle AI Database 오류 번호와 연관시키는 EXCEPTION_INIT 프래그마를 사용할 수 있습니다.
참조:
-
예외성 선언 구문에 대한 자세한 내용은 Oracle AI Database PL/SQL Language Reference를 참조하십시오.
-
예외사항 처리기 구문에 대한 자세한 내용은 Oracle AI Database PL/SQL Language Reference를 참조하십시오.
-
EXCEPTION_INIT 프래그마에 대한 자세한 내용은 Oracle AI Database PL/SQL Language Reference를 참조하십시오
예외 처리기를 사용해야 하는 경우
Oracle은 이러한 경우에만 예외 처리기를 사용할 것을 권장합니다.
-
예외를 예상하고 처리하려고 합니다.
예를 들어, 결국 SELECT INTO 문은 행을 반환하지 않으므로 데이터베이스에서 미리 정의된 예외 NO_DATA_FOUND가 발생하게 됩니다. Example 5-13과 같이 서브 프로그램이나 블록에서 해당 예외(오류가 아님)를 처리한 다음 계속합니다.
-
자원을 포기하거나 마감해야 합니다.
예:
... file := UTL_FILE.OPEN ... BEGIN statement statement]... -- If this code fails for any reason, EXCEPTION WHEN OTHERS THEN UTL_FILE.FCLOSE(file); -- then you want to close the file. RAISE; -- Reraise the exception (very important). END; UTL_FILE.FCLOSE(file); ... -
코드의 최상위 레벨에서 오류를 기록하려고 합니다.
예를 들어, 클라이언트 프로세스가 이 블록을 실행할 수 있습니다.
BEGIN proc(...); EXCEPTION WHEN OTHERS THEN log_error_using_autonomous_transaction(...); RAISE; -- Reraise the exception (very important). END; /또는 클라이언트가 호출하는 독립형 서브 프로그램은 최상위 레벨에서만 동일한 예외 처리 논리를 포함할 수 있습니다.
미리 정의된 예외 사항 처리
미리 정의된 예외를 처리할 수 있습니다. 예 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 AI Database PL/SQL Language Reference에서 미리 정의된 예외에 대한 자세한 내용을 참조하십시오.
사용자 정의 예외 사항 선언 및 처리
유저 정의 예외를 선언하고 처리할 수 있습니다. 예 5-14에서는 두 개의 사용자 정의 예외 사항 wrong_weight와 wrong_score를 선언 및 처리하는 방법을 EMP_EVAL.CALCULATE_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 AI Database PL/SQL Language Reference에서 사용자 정의 예외에 대한 자세한 내용을 참조하십시오.