Recursos Avançados para o Tratamento de Exceções na Linguagem PL/SQL
Veja neste artigo dois temas importantes relacionados ao tratamento de exceções na linguagem PL/SQL: as exceções programadas e os blocos internos para o tratamento de exceções.
1. Introdução
Este artigo aborda dois temas avançados e de fundamental importância no tratamento de exceções na linguagem PL/SQL:
- Exceções programadas: exceção que é disparada apenas em situações definidas pelo programador.
- Blocos internos para tratamento de exceções: recurso que adiciona maior controle ao mecanismo de tratamento de erros.
Como sugestão de leitura deixo o artigo “Tratamento de Exceções de Sistema na linguagem PL/SQL”, onde foram introduzidos os conceitos básicos sobre o tratamento de exceções na linguagem PL/SQL e apresentada a “receita” para realizar o tratamento das exceções de sistema.
2. Exceções Programadas
Caso o programador deseje, poderá definir os seus próprios tipos de exceção na linguagem PL/SQL. Neste caso - ao contrário do que ocorre com as exceções de sistema mostradas artigo citado - a exceção não será disparada automaticamente, mas apenas quando determinadas ações especificadas pelo programador ocorrerem. Para criar exceções programadas, você deve seguir dois passos:
- Criar uma variável do tipo EXCEPTION na seção de declarações de seu procedure ou função.
- Inserir um tratador para a sua exceção no bloco de exceções. O comando RAISE é usado para forçar com que a sua exceção seja disparada.
O programa da Listagem 1 exemplifica a utilização das exceções programadas. Trata-se de um procedure que imprime os n primeiros números ímpares, onde n é um parâmetro de entrada especificado pelo usuário. O procedure possui uma exceção programada que é disparada sempre que n for passado com um valor menor igual a zero.
CREATE OR REPLACE PROCEDURE p_impares(n IN NUMBER) IS
/* -----------------------------------------------------------
PROCEDURE : p_impares
DESCRIÇÃO : imprime os “n” primeiros números ímpares
----------------------------------------------------------- */
i PLS_INTEGER;
j PLS_INTEGER := 1;
e_param_invalido EXCEPTION; -- exceção definida pelo programador
BEGIN
-- esta linha força com que a exceção programada seja disparada
-- caso n seja menor ou igual a zero
IF n <= 0 THEN RAISE e_param_invalido; END IF;
i:=1;
FOR i IN 1..N LOOP
DBMS_OUTPUT.PUT_LINE(j);
j:= j + 2;
END LOOP;
EXCEPTION
WHEN e_param_invalido THEN -- tratamento da exceção programada
DBMS_OUTPUT.PUT_LINE('----------------------------------');
DBMS_OUTPUT.PUT_LINE('Erro!!!');
DBMS_OUTPUT.PUT_LINE('O parametro n deve ser >= 1.');
DBMS_OUTPUT.PUT_LINE('----------------------------------');
END p_impares;
/
Para executar o programa, basta logar no SQL*Plus e chamar o procedure conforme indicado na Figura 1. Se, como é mostrado no exemplo, passarmos o valor 0 como entrada (ou um número negativo), a exceção programada irá disparar, produzindo uma mensagem de erro no console (para a mensagem aparecer, não esqueça de habilitar a saída do console com SET SERVEROUT ON).
Dentro de um programa PL/SQL você pode definir quantas exceções programadas desejar. Para disparar cada exceção basta utilizar o processo mostrado na Listagem 1.
3. Blocos Internos para Tratamento de Exceções
A linguagem PL/SQL permite que você possa embutir blocos anônimos dentro do corpo principal do seu programa. Neste caso, eles são chamados de sub-blocos ou blocos internos. Estes blocos são delimitados com o uso das palavras BEGIN e END e têm como característica mais importante o fato de poderem manter uma seção própria para o tratamento de exceções. Isto adiciona um maior grau de controle ao mecanismo de tratamento de erros. A Figura 2 mostra um exemplo de programa com dois blocos internos.
O esquema da Figura 2 mostra um programa estruturado para funcionar da seguinte forma. Quando começar a executar, entrará no BLOCO INTERNO 1. Se alguma exceção ocorrer nos comandos pertencentes a este bloco, a seção para tratamento de exceções que será executada é a do BLOCO INTERNO 1 e não a seção do corpo principal.
Após o BLOCO INTERNO 1 ser inteiramente processado, o programa passará a executar os comandos do BLOCO INTERNO 2. Isto ocorrerá independentemente do fato de ter ou não ocorrido um erro durante a execução do bloco anterior. Da mesma forma que ocorreu no processamento do BLOCO 1, se algum erro ocorrer durante o processamento do BLOCO INTERNO 2 é a sua própria seção de exceções que será usada para tratá-lo.
O programa da Listagem 2 exemplifica a utilização de blocos internos. Trata-se de um procedure que recebe dois parâmetros numéricos x e y. Inicialmente, o programa realiza a divisão de x por y dentro de um bloco delimitado por BEGIN e END (BLOCO 1). Caso y tenha valor zero, será disparada a exceção associada a este bloco (obs: é uma exceção do tipo ZERO_DIVIDE. Consulte o artigo citado no início do texto se você não ainda não conhece os tipos de exceção da PL/SQL). Em seguida, o programa realiza a divisão de y por x dentro de outro bloco (BLOCO 2). Desta vez, caso x tenha o valor zero, será disparada a exceção associada ao BLOCO 2 (mais uma vez uma exceção do tipo ZERO_DIVIDE).
CREATE OR REPLACE PROCEDURE p_duas_divisoes(x IN NUMBER, y IN NUMBER) IS
/* -----------------------------------------------------------
PROCEDURE : p_duas divisões
DESCRIÇÃO : calcula e imprime x/y e y/x
----------------------------------------------------------- */
resultado1 NUMBER;
resultado2 NUMBER;
BEGIN
-- BLOCO INTERNO 1: Tratamento de x/y
BEGIN
resultado1 := x/y;
DBMS_OUTPUT.PUT_LINE('x/y = ' || TO_CHAR(resultado1));
EXCEPTION
WHEN ZERO_DIVIDE THEN -- tratamento da exceção disparada se y=0
DBMS_OUTPUT.PUT_LINE('----------------------------------');
DBMS_OUTPUT.PUT_LINE('Erro!!!');
DBMS_OUTPUT.PUT_LINE('O parametro y deve ser diferente de 0.');
DBMS_OUTPUT.PUT_LINE('----------------------------------');
END;
-- BLOCO INTERNO 2: Tratamento de y/x
BEGIN
resultado2 := y/x;
DBMS_OUTPUT.PUT_LINE('y/x = ' || TO_CHAR(resultado2));
EXCEPTION
WHEN ZERO_DIVIDE THEN -- tratamento da exceção disparada se x=0
DBMS_OUTPUT.PUT_LINE('----------------------------------');
DBMS_OUTPUT.PUT_LINE('Erro!!!');
DBMS_OUTPUT.PUT_LINE('O parametro x deve ser diferente de 0.');
DBMS_OUTPUT.PUT_LINE('----------------------------------');
END;
END p_duas_divisoes;
/
A Figura 3 apresenta exemplos de três chamadas do programa. Na primeira chamada, passamos y com valor zero, disparando a exceção definida no BLOCO 1. Na segunda chamada, x foi passado com valor 0, fazendo com que fosse disparada a exceção associada ao BLOCO 2. Na terceira chamada, x = 1 e y = 2 e assim o programa roda normalmente, sem que nenhuma exceção seja disparada.
Assim concluímos este artigo abordando o tratamento de exceções na linguagem PL/SQL.
Artigos relacionados
-
Artigo
-
Artigo
-
Artigo
-
Artigo
-
Artigo