Tratando Exceções (Erros do Tempo de Execução)

Você pode tratar exceções que ocorrem no run-time com código PL/SQL.

Consulte Também: Referência de Linguagem PL/SQL do Oracle Database para mais informações sobre como tratar erros de PL/SQL

Sobre Exceções e Handlers de Exceções

Quando ocorre um erro de runtime no código PL/SQL, uma exceção é gerada. Se o subprograma (ou bloco) no qual a exceção é gerada tiver uma parte de tratamento de exceção, o controle será transferido para ele; caso contrário, a execução será interrompida.

Erros de run-time podem surgir em decorrência de falhas em design, erros de codificação, falhas em hardware e muitas outras fontes.

O Oracle Database tem muitas exceções predefinidas, que são geradas automaticamente quando um programa viola as regras do banco de dados ou excede limites dependentes do sistema. Por exemplo, se uma instrução SELECT INTO não retornar linhas, o Oracle Database aumentará a exceção predefinida NO_DATA_FOUND. Para obter um resumo das exceções predefinidas de PL/SQL, consulte Referência de Linguagem do Oracle Database PL/SQL.

O PL/SQL permite que você defina (declare) suas próprias exceções. Uma declaração de exceção tem esta sintaxe:

exception_name EXCEPTION;

Diferentemente de uma exceção predefinida, uma exceção definida por usuário deve ser gerada explicitamente, usando a instrução RAISE ou o procedimento DBMS_STANDARD.RAISE_APPLICATION_ERROR. Por exemplo:

IF condition THEN RAISE exception_name;

Para obter informações sobre o procedimento DBMS_STANDARD.RAISE_APPLICATION_ERROR, consulte Referência de Linguagem PL/SQL do Oracle Database.

A parte de manuseio de exceções de um subprograma contém um ou mais handlers de exceções. Um handler de exceção tem esta sintaxe:

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

("Sobre a Estrutura do Subprograma" mostra onde colocar a parte do tratamento de exceções de um subprograma.)

Um processador de exceções WHEN OTHERS trata erros inesperados de tempo de execução. Se for usado, deverá ser o último. Por exemplo:

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;

Uma alternativa para o handler da exceção WHEN OTHERS é o pragma EXCEPTION_INIT, que associa um nome de exceção definido pelo usuário a um número do erro Oracle Database.

Consulte também:

Quando Usar Handlers de Exceção

Use handlers de exceção somente nas situações a seguir.

Tratando Exceções Predefinidas

É possível tratar exceções predefinidas. Exemplo 5-13 mostra como alterar o procedimento EMP_EVAL.EVAL_DEPARTMENT para tratar a exceção predefinida NO_DATA_FOUND. Faça essa alteração e compile o procedure alterado. (Para obter um exemplo de como alterar o corpo de um pacote, consulte "Tutorial: Declarando Variáveis e Constantes em um Subprograma").

Exemplo 5-13 Tratando a Exceção Predefinida 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;

Consulte também: Referência de Linguagem PL/SQL do Oracle Database para saber mais sobre exceções predefinidas

Declarando e Tratando Exceções Definidas pelo Usuário

Você pode declarar e tratar exceções definidas pelo usuário. O Exemplo 5-14 mostra como alterar a função EMP_EVAL.CALCULATE_SCORE para declarar e tratar duas exceções definidas pelo usuário, incorreto_peso e errado_escore. Faça esta alteração e compile a função alterada. (Para obter um exemplo de como alterar o corpo de um pacote, consulte "Tutorial: Declarando Variáveis e Constantes em um Subprograma").

Exemplo 5-14 Tratando Exceções Definidas pelo Usuário

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;

Consulte Também: Referência de Linguagem do Oracle Database PL/SQL para mais informações sobre exceções definidas pelo usuário