Ausnahmen behandeln (Laufzeitfehler)
Mit PL/SQL-Code können Sie Ausnahmen verarbeiten, die zur Laufzeit auftreten.
Siehe auch: Oracle Database PL/SQL Language Reference, um weitere Informationen zum Handling von PL/SQL-Fehlern zu erhalten
Info zu Ausnahmen und Ausnahme-Handlern
Wenn in PL/SQL-Code ein Runtime-Fehler auftritt, wird eine Ausnahme ausgelöst. Wenn das Unterprogramm (oder Block), in dem die Ausnahme ausgelöst wird, über einen Teil mit Ausnahmehandling verfügt, wird das Steuerelement an diese übertragen. Andernfalls wird das Ausführen angehalten.
Laufzeitfehler können auf Konstruktionsfehler, Fehler im Code, auf Hardwarefehler und vieles andere mehr zurückgeführt werden.
Oracle Database verfügt über viele vordefinierte Ausnahmen, die automatisch ausgelöst werden, wenn ein Programm gegen Datenbankregeln verstößt oder systemabhängige Grenzwerte überschreitet. Beispiel: Wenn eine SELECT INTO-Anweisung keine Zeilen zurückgibt, löst Oracle Database die vordefinierte Ausnahme NO_DATA_FOUND aus. Eine Übersicht über vordefinierte PL/SQL-Ausnahmen finden Sie in Oracle Database PL/SQL Language Reference.
Mit PL/SQL können Sie eigene Ausnahmen definieren (deklarieren). Eine Ausnahmedeklaration weist folgende Syntax auf:
exception_name EXCEPTION;
Im Gegensatz zu vordefinierten Ausnahmen müssen benutzerdefinierte Ausnahmen explizit ausgelöst werden. Verwenden Sie dabei entweder die Anweisung RAISE oder die Prozedur DBMS_STANDARD.RAISE_APPLICATION_ERROR. Beispiel:
IF condition THEN RAISE exception_name;
Informationen zur Prozedur DBMS_STANDARD.RAISE_APPLICATION_ERROR finden Sie in Oracle Database PL/SQL Language Reference.
Der Ausnahmehandlingteil eines Unterprogramms enthält einen oder mehrere Ausnahme-Handler. Ein Ausnahme-Handler weist folgende Syntax auf:
WHEN { exception_name [ OR exception_name ]... | OTHERS } THEN
statement; [ statement; ]...
("Informationen zur Unterprogrammstruktur" zeigt, wo der Exception-Behandlungsteil eines Unterprogramms abgelegt wird.)
Mit dem Ausnahme-Handler WHEN OTHERS werden unerwartete Laufzeitfehler verarbeitet. Dieser muss, wenn er verwendet wird, an letzter Stelle stehen. Beispiel:
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;
Eine Alternative zum Ausnahme-Handler WHEN OTHERS ist das Pragma EXCEPTION_INIT, das einen benutzerdefinierten Exception-Namen mit einer Oracle Database-Fehlernummer verknüpft.
Siehe:
-
Oracle Database PL/SQL Language Reference für weitere Informationen zur Syntax von Ausnahmedeklaration
-
Oracle Database PL/SQL Language Reference für weitere Informationen zur Exception-Handler-Syntax
-
Weitere Informationen zum Pragma EXCEPTION_INIT finden Sie in Oracle Database PL/SQL Language Reference.
Wann Exception Handler verwendet werden sollten
Verwenden Sie Exception Handler nur in den folgenden Situationen.
-
Sie erwarten eine Ausnahme und möchten sie behandeln.
Beispiel: Eine SELECT INTO-Anweisung gibt am Ende keine Zeilen zurück, sodass Oracle Database die vordefinierte Exception NO_DATA_FOUND auslöst. Sie möchten, dass das Unterprogramm oder der Block diese Ausnahme verarbeitet (was kein Fehler ist) und dann wie in Beispiel 5-13 fortfahren.
-
Sie müssen eine Ressource aufgeben oder schließen, wie im folgenden Beispiel gezeigt.
... 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); ... -
Auf der obersten Ebene des Codes, wenn Sie den Fehler protokollieren möchten.
Beispiel: Ein Clientprozess kann diesen Block aussetzen:
BEGIN proc(...); EXCEPTION WHEN OTHERS THEN log_error_using_autonomous_transaction(...); RAISE; -- Reraise the exception (very important). END; /Alternativ kann das Standalone-Unterprogramm, das der Client aufruft, dieselbe Exception-Behandlungslogik enthalten, jedoch nur auf der obersten Ebene.
Vordefinierte Ausnahmen handhaben
Sie können vordefinierte Ausnahmen verarbeiten. Beispiel 5-13 zeigt, wie Sie die EMP_EVAL.EVAL_DEPARTMENT-Prozedur ändern, um die vordefinierte Ausnahme NO_DATA_FOUND zu behandeln. Nehmen Sie die Änderung vor, und kompilieren Sie die geänderte Prozedur. (Ein Beispiel zum Ändern eines Package-Bodys erhalten Sie in "Tutorial: Variablen und Konstanten in Unterprogrammen deklarieren".)
Beispiel 5-13: Vordefinierte Ausnahme NO_DATA_FOUND behandeln
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;
Siehe auch: Oracle Database PL/SQL Language Reference, um weitere Informationen zu vordefinierten Ausnahmen zu zu erhalten
Benutzerdefinierte Ausnahmen deklarieren und handhaben
Sie können benutzerdefinierte Exceptions deklarieren und behandeln. Beispiel 5-14 zeigt, wie Sie die Funktion EMP_EVAL.CALCULATE_SCORE ändern können, um zwei benutzerdefinierte Ausnahmen zu deklarieren und um zu handhaben: wrong_weight und wrong_score. Nehmen Sie diese Änderung vor, und kompilieren Sie die geänderte Funktion. (Ein Beispiel zum Ändern eines Package-Bodys erhalten Sie in "Tutorial: Variablen und Konstanten in Unterprogrammen deklarieren".)
Beispiel 5-14: Benutzerdefinierte Ausnahmen behandeln
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;
Siehe auch: Oracle Database PL/SQL-Sprachreferenzen für weitere Informationen zu benutzerdefinierten Ausnahmen