PL / SQL - Exceções

Neste capítulo, discutiremos Exceções em PL / SQL. Uma exceção é uma condição de erro durante a execução de um programa. PL / SQL oferece suporte a programadores para capturar tais condições usandoEXCEPTIONbloco no programa e uma ação apropriada é executada contra a condição de erro. Existem dois tipos de exceções -

  • Exceções definidas pelo sistema
  • Exceções definidas pelo usuário

Sintaxe para tratamento de exceções

A sintaxe geral para tratamento de exceções é a seguinte. Aqui você pode listar quantas exceções puder controlar. A exceção padrão será tratada usandoWHEN others THEN -

DECLARE 
   <declarations section> 
BEGIN 
   <executable command(s)> 
EXCEPTION 
   <exception handling goes here > 
   WHEN exception1 THEN  
      exception1-handling-statements  
   WHEN exception2  THEN  
      exception2-handling-statements  
   WHEN exception3 THEN  
      exception3-handling-statements 
   ........ 
   WHEN others THEN 
      exception3-handling-statements 
END;

Exemplo

Vamos escrever um código para ilustrar o conceito. Estaremos usando a tabela CLIENTES que criamos e usamos nos capítulos anteriores -

DECLARE 
   c_id customers.id%type := 8; 
   c_name customerS.Name%type; 
   c_addr customers.address%type; 
BEGIN 
   SELECT  name, address INTO  c_name, c_addr 
   FROM customers 
   WHERE id = c_id;  
   DBMS_OUTPUT.PUT_LINE ('Name: '||  c_name); 
   DBMS_OUTPUT.PUT_LINE ('Address: ' || c_addr); 

EXCEPTION 
   WHEN no_data_found THEN 
      dbms_output.put_line('No such customer!'); 
   WHEN others THEN 
      dbms_output.put_line('Error!'); 
END; 
/

Quando o código acima é executado no prompt SQL, ele produz o seguinte resultado -

No such customer!  

PL/SQL procedure successfully completed.

O programa acima exibe o nome e o endereço de um cliente cujo ID é fornecido. Como não há nenhum cliente com ID de valor 8 em nosso banco de dados, o programa gera a exceção de tempo de execuçãoNO_DATA_FOUND, que é capturado no EXCEPTION block.

Levantando exceções

As exceções são levantadas pelo servidor de banco de dados automaticamente sempre que houver algum erro interno do banco de dados, mas as exceções podem ser levantadas explicitamente pelo programador usando o comando RAISE. A seguir está a sintaxe simples para levantar uma exceção -

DECLARE 
   exception_name EXCEPTION; 
BEGIN 
   IF condition THEN 
      RAISE exception_name; 
   END IF; 
EXCEPTION 
   WHEN exception_name THEN 
   statement; 
END;

Você pode usar a sintaxe acima para gerar a exceção padrão do Oracle ou qualquer exceção definida pelo usuário. Na próxima seção, daremos um exemplo de como gerar uma exceção definida pelo usuário. Você pode aumentar as exceções padrão do Oracle de maneira semelhante.

Exceções definidas pelo usuário

PL / SQL permite que você defina suas próprias exceções de acordo com a necessidade de seu programa. Uma exceção definida pelo usuário deve ser declarada e, em seguida, gerada explicitamente, usando uma instrução RAISE ou o procedimentoDBMS_STANDARD.RAISE_APPLICATION_ERROR.

A sintaxe para declarar uma exceção é -

DECLARE 
   my-exception EXCEPTION;

Exemplo

O exemplo a seguir ilustra o conceito. Este programa pede um ID de cliente, quando o usuário insere um ID inválido, a exceçãoinvalid_id é gerado.

DECLARE 
   c_id customers.id%type := &cc_id; 
   c_name customerS.Name%type; 
   c_addr customers.address%type;  
   -- user defined exception 
   ex_invalid_id  EXCEPTION; 
BEGIN 
   IF c_id <= 0 THEN 
      RAISE ex_invalid_id; 
   ELSE 
      SELECT  name, address INTO  c_name, c_addr 
      FROM customers 
      WHERE id = c_id;
      DBMS_OUTPUT.PUT_LINE ('Name: '||  c_name);  
      DBMS_OUTPUT.PUT_LINE ('Address: ' || c_addr); 
   END IF; 

EXCEPTION 
   WHEN ex_invalid_id THEN 
      dbms_output.put_line('ID must be greater than zero!'); 
   WHEN no_data_found THEN 
      dbms_output.put_line('No such customer!'); 
   WHEN others THEN 
      dbms_output.put_line('Error!');  
END; 
/

Quando o código acima é executado no prompt SQL, ele produz o seguinte resultado -

Enter value for cc_id: -6 (let's enter a value -6) 
old  2: c_id customers.id%type := &cc_id; 
new  2: c_id customers.id%type := -6; 
ID must be greater than zero! 
 
PL/SQL procedure successfully completed.

Exceções pré-definidas

A PL / SQL fornece muitas exceções predefinidas, que são executadas quando qualquer regra do banco de dados é violada por um programa. Por exemplo, a exceção predefinida NO_DATA_FOUND é gerada quando uma instrução SELECT INTO não retorna nenhuma linha. A tabela a seguir lista algumas das exceções predefinidas importantes -

Exceção Erro Oracle SQLCODE Descrição
ACCESS_INTO_NULL 06530 -6530 Ele é gerado quando um objeto nulo é automaticamente atribuído a um valor.
CASE_NOT_FOUND 06592 -6592 Ele é gerado quando nenhuma das opções na cláusula WHEN de uma instrução CASE é selecionada e não há nenhuma cláusula ELSE.
COLLECTION_IS_NULL 06531 -6531 Ele é gerado quando um programa tenta aplicar métodos de coleta diferentes de EXISTS a uma tabela ou varray aninhada não inicializada, ou o programa tenta atribuir valores aos elementos de uma tabela ou varray aninhada não inicializada.
DUP_VAL_ON_INDEX 00001 -1 Ele é gerado quando valores duplicados são tentados a serem armazenados em uma coluna com índice exclusivo.
INVALID_CURSOR 01001 -1001 Ele é gerado quando são feitas tentativas de fazer uma operação de cursor que não é permitida, como fechar um cursor não aberto.
NÚMERO INVÁLIDO 01722 -1722 Ele é gerado quando a conversão de uma string de caracteres em um número falha porque a string não representa um número válido.
LOGIN_DENIED 01017 -1017 Ele é gerado quando um programa tenta fazer logon no banco de dados com um nome de usuário ou senha inválidos.
NENHUM DADO ENCONTRADO 01403 +100 É gerado quando uma instrução SELECT INTO não retorna nenhuma linha.
NOT_LOGGED_ON 01012 -1012 Ele é gerado quando uma chamada de banco de dados é emitida sem estar conectada ao banco de dados.
PROGRAM_ERROR 06501 -6501 Ele é gerado quando o PL / SQL tem um problema interno.
ROWTYPE_MISMATCH 06504 -6504 Ele é gerado quando um cursor busca o valor em uma variável com tipo de dados incompatível.
SELF_IS_NULL 30625 -30625 Ele é gerado quando um método de membro é chamado, mas a instância do tipo de objeto não foi inicializada.
STORAGE_ERROR 06500 -6500 Ele é gerado quando o PL / SQL fica sem memória ou a memória é corrompida.
TOO_MANY_ROWS 01422 -1422 É gerado quando uma instrução SELECT INTO retorna mais de uma linha.
VALUE_ERROR 06502 -6502 É gerado quando ocorre um erro aritmético, de conversão, truncamento ou restrição de tamanho.
DIVISÃO POR ZERO 01476 1476 Ele é gerado quando é feita uma tentativa de dividir um número por zero.