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. |