Tratamento de exceções em Oracle PL/SQL (exemplos)
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 ser executada devido a um erro ocorrido em tempo de execução. Esses erros não serão capturados no momento da compilação e, portanto, precisam ser tratados apenas em tempo de execução.
Por exemplo, se o mecanismo PL/SQL receber uma instrução para dividir qualquer número por '0', o mecanismo PL/SQL lançará isso como uma exceção. A exceção só é gerada em tempo de execução pelo mecanismo PL/SQL.
As exceções impedirão a execução do programa, portanto, para evitar tal condição, elas precisam ser capturadas e tratadas separadamente. Este processo é denominado Tratamento de Exceções, no qual o programador trata a exceção que pode ocorrer em tempo de execução.
Sintaxe de tratamento de exceções
As exceções são tratadas no nível do bloco, ou seja, uma vez que se ocorrer alguma exceção em qualquer bloco, o controle sairá da parte de execução desse bloco. A exceção será então tratada na parte de tratamento de exceções desse bloco. Depois de tratar a exceção, não é possível reenviar o controle para a seção de execução daquele bloco.
A sintaxe abaixo explica como capturar e tratar a 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 tratar a exceção.
- Cada condição WHEN é seguida pelo nome da exceção que deve ser gerada no tempo de execução.
- Quando qualquer exceção é levantada em tempo de execução, o mecanismo PL/SQL procurará na parte de tratamento de exceções essa exceção específica. Ele iniciará a partir da primeira cláusula 'WHEN' e, sequencialmente, fará a pesquisa.
- Se encontrar o tratamento de exceção para a exceção que foi levantada, ele executará essa parte específica do código de tratamento.
- Se nenhuma cláusula 'WHEN' estiver presente para a exceção que foi levantada, o mecanismo PL/SQL executará a parte 'WHEN OTHERS' (se presente). Isso é comum para todas as exceções.
- Após executar a exceção, o controle da peça sairá do bloco atual.
- Apenas uma parte de exceção pode ser executada para um bloco em tempo de execução. Após executá-lo, o controlador pulará a parte restante do tratamento de exceções e sairá do bloco atual.
Nota: WHEN OTHERS deve estar sempre na última posição da sequência. A parte de tratamento de exceção presente após WHEN OTHERS nunca será executada, pois o controle sairá do bloco após a execução de WHEN OTHERS.
Tipos de exceção
Existem dois tipos de exceções em Pl/SQL.
- Exceções predefinidas
- Exceção definida pelo usuário
Exceções predefinidas
Oracle predefiniu alguma exceção comum. Essas exceções têm um nome de exceção e um número de erro exclusivos. Estas exceções já estão definidas no pacote 'STANDARD' em Oracle. No código, podemos usar diretamente esses nomes de exceção predefinidos para tratá-los.
Abaixo estão algumas exceções predefinidas
Exceção | Erro de código | Motivo da Exceção |
---|---|---|
ACCESS_INTO_NULL | ORA-06530 | Atribuir um valor aos atributos de objetos não inicializados |
CASE_NOT_FOUND | ORA-06592 | Nenhuma cláusula 'WHEN' na instrução CASE foi satisfeita e nenhuma cláusula 'ELSE' foi especificada |
COLLECTION_IS_NULL | ORA-06531 | Usando métodos de coleção (exceto EXISTS) ou acessando atributos de coleção em coleções não inicializadas |
CURSOR_ALREADY_OPEN | ORA-06511 | Tentando abrir um cursor que já está aberto |
DUP_VAL_ON_INDEX | ORA-00001 | Armazenando um valor duplicado em uma coluna de banco de dados que é restrita por um índice exclusivo |
INVALID_CURSOR | ORA-01001 | Operações ilegais de cursor, como fechar um cursor não aberto |
NÚMERO INVÁLIDO | ORA-01722 | A conversão do caractere em um número falhou devido a um caractere numérico inválido |
NENHUM DADO ENCONTRADO | ORA-01403 | Quando a instrução 'SELECT' que contém a cláusula INTO não busca nenhuma linha. |
ROW_MISMATCH | ORA-06504 | Quando o tipo de dados da variável do cursor é incompatível com o tipo de retorno real do cursor |
SUBSCRIPT_BEYOND_COUNT | ORA-06533 | Referindo-se à coleção por um número de índice maior que o tamanho da coleção |
SUBSCRIPT_OUTSIDE_LIMIT | ORA-06532 | Referindo a coleção por um número de índice que está fora da faixa legal (ex.: -1) |
TOO_MANY_ROWS | ORA-01422 | Quando uma instrução 'SELECT' com cláusula INTO retorna mais de uma linha |
VALUE_ERROR | ORA-06502 | Erro aritmético ou de restrição de tamanho (por exemplo: atribuir um valor a uma variável que é maior que o tamanho da variável) |
ZERO_DIVIDE | ORA-01476 | Dividindo um número por '0' |
Exceção definida pelo usuário
In Oracle, além das exceções predefinidas acima, o programador pode criar suas próprias exceções e tratá-las. Eles podem ser criados em nível de subprograma na parte de declaração. Estas exceções são visíveis apenas nesse subprograma. A exceção definida na especificação do pacote é uma exceção pública e é visível onde quer que o pacote esteja acessível.
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 'nome_exceção' é definida como tipo 'EXCEPÇÃO'.
- Isso pode ser usado de maneira semelhante a 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 'nome_exceção' é definida como tipo 'EXCEPÇÃO' na especificação do pacote de .
- Isto pode ser usado no banco de dados onde quer que o pacote 'package_name' possa ser chamado.
Exceção de aumento PL/SQL
Todas as exceções predefinidas são levantadas implicitamente sempre que ocorre o erro. Mas as exceções definidas pelo usuário precisam ser levantadas explicitamente. Isto pode ser conseguido usando a palavra-chave 'RAISE'. Isso pode ser usado de qualquer uma das maneiras mencionadas abaixo.
Se 'RAISE' for usado separadamente no programa, ele propagará a exceção já levantada para o bloco pai. Somente no bloco de exceção pode ser usado conforme mostrado abaixo.
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 no bloco de tratamento de exceções.
- Sempre que o programa encontrar a exceção “nome_exceção”, a exceção será tratada e será concluída normalmente
- Mas a palavra-chave 'RAISE' na parte de tratamento de exceções propagará esta exceção específica para o programa pai.
Nota: Ao gerar a exceção para o bloco pai, a exceção que está sendo levantada também deve estar visível no bloco pai, caso contrário, o Oracle lançará um erro.
- Podemos usar a palavra-chave 'RAISE' seguida pelo nome da exceção para gerar aquela exceção específica definida/predefinida pelo usuário. Isso pode ser usado tanto na parte de execução quanto na parte de tratamento de exceções para gerar a exceção.
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_exceção”.
- Isso gerará essa exceção específica no momento da execução e precisa ser tratada ou levantada posteriormente.
Exemplo 1: Neste exemplo, veremos
- Como declarar a exceção
- Como levantar a exceção declarada e
- Como propagá-lo para o bloco principal
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: /
Explicação do código:
- Linha de código 2: Declarando a variável 'sample_exception' como tipo EXCEPTION.
- Linha de código 3: Declarando procedimento nested_block.
- Linha de código 6: Imprimindo a instrução “Dentro do bloco aninhado”.
- Linha de código 7: Imprimindo a instrução “Levantando sample_exception do bloco aninhado”.
- Linha de código 8: Levantando a exceção usando 'RAISE sample_exception'.
- Linha de código 10: Manipulador de exceção para exceção sample_exception no bloco aninhado.
- Linha de código 11: Imprimindo a instrução 'Exceção capturada em bloco aninhado. Subindo para o bloco principal'.
- Linha de código 12: Levantando a exceção para o bloco principal (propagando para o bloco principal).
- Linha de código 15: Imprimindo a declaração “Dentro do bloco principal”.
- Linha de código 16: Imprimindo a instrução “Chamando bloco aninhado”.
- Linha de código 17: Chamando o procedimento nested_block.
- Linha de código 18: Exceção
- Linha de código 19: Manipulador de exceção para sample_exception no bloco principal.
- Linha de código 20: Imprimindo a instrução “Exceção capturada no bloco principal”.
Pontos importantes a serem observados na exceção
- Na função, uma exceção deve sempre retornar um valor ou aumentar ainda mais a exceção. outro Oracle lançará o erro 'Função retornada sem valor' em tempo de execução.
- Instruções de controle de transação podem ser fornecidas no bloco de tratamento de exceções.
- SQLERRM e SQLCODE são as funções integradas que fornecerão a mensagem e o código de exceção.
- Se uma exceção não for tratada, por padrão, todas as transações ativas naquela sessão serão revertidas.
- RAISE_APPLICATION_ERROR (- , ) pode ser usado em vez de RAISE para gerar o erro com o código do usuário e a mensagem. O código de erro deve ser maior que 20000 e prefixado com '-'.
Resumo
Depois deste capítulo. você deve ser capaz de trabalhar nos seguintes aspectos do Pl SQL exceções
- Lidando com as exceções
- Definir uma exceção
- Levante a exceção
- Propagação de exceção