Tratamento de exceções em Oracle PL/SQL (exemplos)
⚡ Resumo Inteligente
Tratamento de exceções em Oracle PL/SQL captura erros de tempo de execução que impedem a execução de um bloco, permitindo que o mecanismo transfira o controle para uma seção EXCEPTION, onde manipuladores predefinidos, definidos pelo usuário e OUTROS respondem, geram ou propagam erros com segurança.

O que é tratamento de exceções em PL/SQL?
Uma exceção ocorre quando o mecanismo PL/SQL encontra uma instrução que não pode executar devido a um erro que surge em tempo de execução. Esses erros não são detectados em tempo de compilação e, portanto, devem ser tratados somente em tempo de execução.
Por exemplo, se o mecanismo PL/SQL receber uma instrução para dividir um número por zero, ele lançará o erro como uma exceção. A exceção é lançada apenas em tempo de execução pelo mecanismo PL/SQL.
Uma exceção impede a execução do programa, portanto, para evitar essa situação, o erro precisa ser capturado e tratado separadamente. Esse processo é chamado de tratamento de exceções, no qual o programador lida com os erros que podem ocorrer durante a execução.
Sintaxe de tratamento de exceções
As exceções são tratadas no nível do bloco. Quando uma exceção ocorre em um bloco, o controle sai da parte de execução desse bloco e a exceção é tratada na parte de tratamento de exceções do bloco. Após a exceção ser tratada, o controle não pode retornar à seção de execução desse mesmo bloco.
A ilustração abaixo mostra como a seção de execução e a seção de tratamento de exceções estão contidas em um único bloco PL/SQL:
A sintaxe abaixo explica como capturar e tratar uma exceção.
BEGIN <execution block> . . EXCEPTION WHEN <exceptionl_name> THEN <Exception handling code for the “exception 1 _name’' > WHEN OTHERS THEN <Default exception handling code for all exceptions > END;
Explicação da sintaxe:
- Na sintaxe acima, o bloco de tratamento de exceções contém uma série de condições WHEN para lidar com exceções.
- Cada condição WHEN é seguida por um nome de exceção que se espera que seja lançada em tempo de execução.
- Quando uma exceção é lançada em tempo de execução, o mecanismo PL/SQL pesquisa a parte de tratamento de exceções em busca dessa exceção específica, começando pela primeira cláusula WHEN e seguindo sequencialmente.
- Se encontrar um manipulador para a exceção que foi lançada, ele executará o código desse manipulador específico.
- Se nenhuma cláusula WHEN corresponder à exceção gerada, o mecanismo PL/SQL executará a parte WHEN OTHERS, se presente. Esse manipulador é comum a todas as exceções.
- Após a execução do manipulador, o controle sai do bloco atual.
- Apenas um manipulador de exceções pode ser executado por bloco em tempo de execução. Após sua execução, o mecanismo ignora os manipuladores restantes e abandona o bloco atual.
Observação: A instrução `WHEN OTHERS` deve sempre ser colocada por último na sequência. Qualquer manipulador escrito após `WHEN OTHERS` nunca será executado, pois o controle sai do bloco assim que `WHEN OTHERS` for executado.
Tipos de exceção
Existem dois tipos de exceções em PL/SQL.
- Exceções predefinidas
- Exceções definidas pelo usuário
Exceções predefinidas
Oracle possui algumas exceções comuns predefinidas. Cada exceção predefinida tem um nome e um número de erro únicos, e todas elas estão declaradas no pacote STANDARD em OracleNo código, você pode usar esses nomes de exceção predefinidos diretamente para lidar com os erros correspondentes. Muitos deles correspondem diretamente a exceções comuns. SQL erros que você encontra todos os dias.
Abaixo estão algumas exceções predefinidas:
| Exceção | erro Code | Motivo da Exceção |
|---|---|---|
| ACCESS_INTO_NULL | ORA-06530 | Atribuir um valor aos atributos de um objeto não inicializado. |
| CASE_NOT_FOUND | ORA-06592 | Nenhuma das cláusulas WHEN em uma instrução CASE é satisfeita e nenhuma cláusula ELSE é especificada. |
| COLLECTION_IS_NULL | ORA-06531 | Utilizar métodos de coleção (exceto EXISTS) ou acessar atributos de coleção em uma coleção não inicializada. |
| CURSOR_ALREADY_OPEN | ORA-06511 | Tentando abrir um cursor que já está aberto |
| DUP_VAL_ON_INDEX | ORA-00001 | Armazenar um valor duplicado em uma coluna de banco de dados que é limitada por um índice exclusivo. |
| INVALID_CURSOR | ORA-01001 | Operações ilegais com o cursor, como fechar um cursor que não foi aberto. |
| NÚMERO INVÁLIDO | ORA-01722 | A conversão de um caractere para um número falhou devido a um caractere numérico inválido. |
| NENHUM DADO ENCONTRADO | ORA-01403 | Uma instrução SELECT que contém uma cláusula INTO não retorna nenhuma linha. |
| ROW_MISMATCH | ORA-06504 | O tipo de dados da variável cursor é incompatível com o tipo de retorno real do cursor. |
| SUBSCRIPT_BEYOND_COUNT | ORA-06533 | Referir-se a uma coleção por um número de índice maior que o tamanho da coleção. |
| SUBSCRIPT_OUTSIDE_LIMIT | ORA-06532 | Referir-se a uma coleção por um número de índice fora do intervalo legal (por exemplo, -1) |
| TOO_MANY_ROWS | ORA-01422 | Uma instrução SELECT com uma cláusula INTO retorna mais de uma linha. |
| VALUE_ERROR | ORA-06502 | Um erro aritmético ou de restrição de tamanho (por exemplo, atribuir um valor maior que o tamanho da variável). |
| ZERO_DIVIDE | ORA-01476 | Dividir um número por zero |
Exceção definida pelo usuário
Além das exceções predefinidas acima, um programador pode criar exceções personalizadas e tratá-las. Elas são criadas no nível do subprograma, na parte de declaração, e são visíveis apenas dentro desse subprograma. Uma exceção definida na especificação de um pacote é uma exceção pública e é visível em qualquer lugar onde o pacote possa ser acessado.
Sintaxe: No nível do subprograma
DECLARE <exception_name> EXCEPTION; BEGIN <Execution block> EXCEPTION WHEN <exception_name> THEN <Handler> END;
- Na sintaxe acima, a variável 'exception_name' é definida como o tipo EXCEPTION.
- Ele pode então ser usado da mesma forma que uma exceção predefinida.
Sintaxe: No nível de especificação do pacote
CREATE PACKAGE <package_name> IS <exception_name> EXCEPTION; . . END <package_name>;
- Na sintaxe acima, a variável 'exception_name' é definida como o tipo EXCEPTION na especificação do pacote de .
- Ele pode ser usado em todo o banco de dados, sempre que o pacote 'package_name' puder ser chamado.
Exceção de aumento PL/SQL
Todas as exceções predefinidas são lançadas implicitamente sempre que o erro correspondente ocorre. Exceções definidas pelo usuário, no entanto, devem ser lançadas explicitamente usando a palavra-chave RAISE. RAISE pode ser usado das maneiras mostradas abaixo.
Se RAISE for usado sozinho dentro de um manipulador, ele propagará a exceção já lançada para o bloco pai. Ele só pode ser usado dentro de um bloco de exceção, como mostrado abaixo.
A captura de tela abaixo mostra o RAISE sendo usado sozinho para relançar uma exceção no bloco envolvente:
CREATE [ PROCEDURE | FUNCTION ] AS BEGIN <Execution block> EXCEPTION WHEN <exception_name> THEN <Handler> RAISE; END;
Explicação da sintaxe:
- Na sintaxe acima, a palavra-chave RAISE é usada dentro do bloco de tratamento de exceções.
- Sempre que o programa encontra a exceção 'nome_da_exceção', a exceção é tratada e a execução ocorre normalmente.
- A palavra-chave RAISE no manipulador propaga essa mesma exceção para o programa pai.
Observação: Ao gerar uma exceção para o bloco pai, a exceção gerada também deve ser visível no bloco pai; caso contrário, Oracle lança um erro.
Você também pode usar a palavra-chave RAISE seguida do nome da exceção para gerar essa exceção específica, definida pelo usuário ou predefinida. Essa forma pode ser usada tanto na parte de execução quanto na parte de tratamento de exceções.
A captura de tela abaixo mostra o comando RAISE seguido pelo nome da exceção para gerar uma exceção específica:
CREATE [ PROCEDURE | FUNCTION ] AS BEGIN <Execution block> RAISE <exception_name> EXCEPTION WHEN <exception_name> THEN <Handler> END;
Explicação da sintaxe:
- Na sintaxe acima, a palavra-chave RAISE é usada na parte de execução, seguida pela exceção 'nome_da_exceção'.
- Isso gera essa exceção específica em tempo de execução, e ela precisa ser tratada ou relançada.
1 exemplo: Neste exemplo, veremos:
- Como declarar uma exceção
- Como gerar a exceção declarada
- Como propagá-lo para o bloco principal
A captura de tela abaixo mostra o bloco completo que declara a exceção `sample_exception`, a gera dentro de um bloco aninhado e a propaga para o bloco principal:
A captura de tela a seguir mostra o mesmo exemplo em continuação, onde o bloco principal finalmente captura a exceção propagada:
DECLARE Sample_exception EXCEPTION; PROCEDURE nested_block IS BEGIN Dbms_output.put_line('Inside nested block'); Dbms_output.put_line('Raising sample_exception from nested block'); RAISE sample_exception; EXCEPTION WHEN sample_exception THEN Dbms_output.put_line ('Exception captured in nested block. Raising to main block'); RAISE; END; BEGIN Dbms_output.put_line('Inside main block'); Dbms_output.put_line('Calling nested block'); Nested_block; EXCEPTION WHEN sample_exception THEN Dbms_output.put_line ('Exception captured in main block'); END; /
Code Explicação:
- Code linha 2: Declarando a variável 'sample_exception' como um tipo EXCEPTION.
- Code linha 3: Declarando o procedimento nested_block.
- Code linha 6: Imprimindo a declaração “Dentro de um bloco aninhado”.
- Code linha 7: Imprimindo a mensagem “Gerando sample_exception de bloco aninhado”.
- Code linha 8: Levantando a exceção usando 'RAISE sample_exception'.
- Code linha 10: Tratador de exceção para a exceção sample_exception no bloco aninhado.
- Code linha 11: Exibindo a mensagem "Exceção capturada em bloco aninhado. Levantando para o bloco principal".
- Code linha 12: Gerando a exceção para o bloco principal (propagando-a).
- Code linha 15: Imprimindo a declaração “Dentro do bloco principal”.
- Code linha 16: Imprimindo a instrução “Chamando bloco aninhado”.
- Code linha 17: Chamando o procedimento nested_block.
- Code linha 19: Manipulador de exceção para sample_exception no bloco principal.
- Code linha 20: Exibindo a mensagem "Exceção capturada no bloco principal".
Pontos importantes a serem observados na exceção
- Em uma função, uma exceção deve sempre retornar um valor ou propagar a exceção; caso contrário, Oracle Gera um erro do tipo "Função retornou sem valor" em tempo de execução.
- declarações de controle de transação pode ser emitido dentro do bloco de tratamento de exceções.
- SQLERRM e SQLCODE são funções internas que retornam a mensagem de exceção e o código de exceção, respectivamente.
- Se uma exceção não for tratada, por padrão todas as transações ativas nessa sessão serão revertidas.
- RAISE_APPLICATION_ERROR (- , ) pode ser usado em vez de RAISE para gerar um erro com um código e mensagem personalizados. O código de erro deve estar entre -20000 e -20999.





