Propagação de Exceções em PL/SQL Oracle

Bem-vindo ao nosso artigo sobre Propagação de Exceções em PL/SQL Oracle. Hoje, vamos explorar em detalhes como as exceções se propagam em diferentes partes de um bloco PL/SQL e como podemos controlar esse comportamento.

Introdução à Propagação de Exceções

A propagação de exceções refere-se às regras que governam como as exceções são levantadas e tratadas em diferentes partes de um bloco PL/SQL. Essas regras são cruciais para entender como lidar com erros em situações complexas.

Vamos explorar três cenários principais:

  1. Erros na seção executável
  2. Erros na seção declarativa
  3. Erros na seção de tratamento de exceções

1. Erros na Seção Executável

Quando um erro ocorre na seção executável de um bloco PL/SQL, o comportamento é relativamente direto. Vamos revisar este caso.

Neste caso:

  1. Se uma exceção específica está associada ao erro, o controle passa para a seção de tratamento de exceções do bloco.
  2. Após a execução das instruções associadas à exceção, o controle passa para o ambiente host ou para o bloco envolvente.
  3. Se não houver um manipulador de exceção para este erro, a exceção é propagada para o bloco envolvente (bloco externo).
  4. Se nenhum manipulador de exceção for encontrado, a execução do programa é interrompida e o controle é transferido para o ambiente host.

2. Erros na Seção Declarativa

Erros na seção declarativa são mais complicados. Vamos examinar este cenário em detalhes.

Quando executado, este exemplo produz o seguinte resultado:

Observe que, mesmo tendo um manipulador de exceção para VALUE_ERROR, o bloco não consegue executar com sucesso. Isso nos leva à conclusão de que quando um erro de tempo de execução ocorre na seção declarativa do bloco PL/SQL, a seção de tratamento de exceções deste bloco não é capaz de capturar o erro.

Agora, vamos considerar uma versão modificada com blocos PL/SQL aninhados:

Quando executado, este exemplo produz:

Nesta versão, o bloco PL/SQL está envolto por outro bloco, e o programa consegue completar. A exceção definida no bloco externo é levantada quando o erro ocorre na seção declarativa do bloco interno. Portanto, podemos concluir que quando um erro de tempo de execução ocorre na seção declarativa do bloco interno, a exceção é imediatamente propagada para o bloco envolvente (externo).

3. Erros na Seção de Tratamento de Exceções

Agora, vamos considerar o terceiro caso, onde um erro de tempo de execução ocorre na seção de tratamento de exceções do bloco. Assim como no caso anterior, se não houver um bloco externo, a execução do programa é interrompida e o controle passa para o ambiente host.

Considere o seguinte exemplo:

Quando executado, este exemplo produz:

Como você pode ver, a instrução de atribuição na seção executável do bloco causa um erro. Por sua vez, o controle é transferido para a seção de tratamento de exceções do bloco. No entanto, a instrução de atribuição na seção de tratamento de exceções do bloco levanta o mesmo erro. Como resultado, a saída deste exemplo exibe a mesma mensagem de erro duas vezes.

Agora, vamos considerar uma versão modificada do mesmo exemplo com blocos PL/SQL aninhados:

Quando executado, esta versão produz:

Nesta versão do exemplo, o bloco PL/SQL está envolto por outro bloco, e o programa consegue completar. Neste caso, a exceção definida no bloco externo é levantada quando o erro ocorre na seção de tratamento de exceções do bloco interno. Portanto, podemos concluir que quando um erro de tempo de execução ocorre na seção de tratamento de exceções do bloco interno, a exceção é imediatamente propagada para o bloco envolvente.

Re-levantamento de Exceções

Em algumas ocasiões, você pode querer ser capaz de parar seu programa se um certo tipo de erro ocorrer. Em outras palavras, você pode querer tratar uma exceção no bloco interno e depois passá-la para o bloco externo. Este processo é chamado de re-levantamento de exceções.

Considere o seguinte exemplo:

Neste exemplo, a exceção e_exception é primeiro declarada no bloco externo, depois levantada no bloco interno. Como resultado, o controle é transferido para a seção de tratamento de exceções do bloco interno. A instrução RAISE na seção de tratamento de exceções do bloco causa a propagação da exceção para a seção de tratamento de exceções do bloco externo. Observe que quando a instrução RAISE é usada na seção de tratamento de exceções do bloco interno, ela não é seguida pelo nome da exceção.

Quando executado, este exemplo produz a seguinte saída:

Considerações Importantes

  1. Quando uma exceção é levantada em um bloco PL/SQL que não tem um mecanismo de tratamento de exceções apropriado e não está envolto por outro bloco, o controle é transferido para o ambiente host, e o programa não consegue completar com sucesso. Por exemplo:

Isso resultará em:

  1. Quando uma exceção é re-levantada em um bloco que não está envolto por nenhum outro bloco, o programa não consegue completar com sucesso. Por exemplo:

Isso resultará em:

O Problema

  • O código levanta uma exceção e a captura corretamente
  • No entanto, ao invés de tratar a exceção, ele simplesmente a re-levanta
  • Como não há nenhum bloco externo, a exceção re-levantada não é capturada
  • Isso resulta em um erro não tratado: “ORA-06510: PL/SQL: unhandled user-defined exception”

Consequências

  • O programa termina abruptamente
  • Nenhum tratamento real da exceção é realizado
  • Qualquer lógica que deveria ser executada após este bloco não será executada

Solução: Usar Bloco Externo

  1. Apenas uma exceção pode ser tratada por vez em um bloco. Se uma nova exceção é levantada durante o tratamento, ela se propaga para o bloco externo.

Exercício Prático Detalhado

Preparação do Ambiente

Primeiro, caso ainda não tenha criado, vamos criar as tabelas necessárias e inserir alguns dados de amostra. Execute os seguintes comandos SQL:

 

Agora Vamos criar um exemplo mais complexo para demonstrar todos os aspectos da propagação de exceções que discutimos:

Este procedimento demonstra:

  1. Uso de sub-procedimentos para organizar a lógica
  2. Propagação de exceções entre sub-procedimentos e o bloco principal
  3. Re-levantamento de exceções personalizadas
  4. Tratamento de erros na seção declarativa (através do bloco aninhado em validate_student)
  5. Tratamento de erros na seção de tratamento de exceções (em check_course_limit)
  6. Re-levantamento de exceções para o chamador do procedimento

Para testar:

Conclusão

A compreensão da propagação de exceções é crucial para escrever código PL/SQL robusto e confiável. Lembre-se:

  1. Erros na seção declarativa não podem ser tratados no mesmo bloco, mas podem ser capturados por um bloco externo.
  2. Erros na seção de tratamento de exceções propagam-se imediatamente para o bloco envolvente.
  3. Use blocos aninhados para maior controle sobre a propagação de exceções.
  4. O re-levantamento de exceções permite tratar uma exceção e depois passá-la para um nível superior.
  5. Sempre considere como as exceções se propagarão em sua estrutura de blocos PL/SQL.
  6. Apenas uma exceção pode ser tratada por vez em um bloco.
  7. Exceções não tratadas em blocos não aninhados resultam na terminação do programa.

Praticar com diferentes cenários ajudará você a dominar este conceito importante. Continue explorando e experimentando com propagação de exceções em suas estruturas de blocos PL/SQL para criar código mais robusto e confiável.

Este artigo abrangente sobre propagação de exceções em PL/SQL Oracle fornece uma base sólida para entender e implementar estratégias eficazes de tratamento de erros em seus programas. Lembre-se de que o tratamento adequado de exceções é fundamental para criar aplicações PL/SQL robustas e de fácil manutenção.

Scroll to Top