[firebase-br] Tratamento de "Exception" dentro de Storage Procedure

Carlos H. Cantu listas em warmboot.com.br
Qua Fev 4 09:39:50 -03 2009


O exemplo do livro está incorreto. Se a intenção é fazer um LOG da
exceção que ocorreu, gravando-o em uma tabela do banco, você
obviamente não pode dar um re-raise na exceção, pois o insert do log
seria desfeito (rollback).

No caso, se a idéia é interromper a execução da procedure, então ao
invés de dar um re-raise, use o EXIT.

Desculpe pelo erro do exemplo do livro. Já estou inserindo isso na
página de erratas. Por mais que a gente se esforce, sempre acaba
passando alguma coisa.

Para facilitar, segue um exemplo corrigido:

CREATE PROCEDURE TESTE
as
declare variable a numeric(15,2);
declare variable x numeric(15,2);
begin
  insert into tab1 (campo) values ('insert normal');
  a = 0;
  x = 1 / a; -- forca dar um erro (divisao por zero)
  when any do
  begin
    insert into LOG (mensagem) values ('ERRO ao executar procedure blablabla'); -- armazena o log na tabela LOG
    exit; -- sai da procedure. O insert em tab1 nao sera gravado por causa da exceção que ocorreu
  end
end

[]s
Carlos H. Cantu
www.FireBase.com.br - www.firebirdnews.org
www.warmboot.com.br - blog.firebase.com.br

ECdON> Pessoal

ECdON> Olhei o exemplo do livro FireBird 2 do Cantu, dê uma olhada na pág. 179, é
ECdON> exatamente isto.
ECdON> Acho que não ficou bem claro o que eu quero fazer.

ECdON> -- A ser disparado um exception, a SP é desviada para o WHEN any do ;
ECdON> -- Executa o insert em uma tabela;
ECdON> -- E dispara outro exception (re-raise), que termina a execução da SP.
ECdON> -- COMMIT;

ECdON> Pelo exemplo do livro é esperado que:
ECdON> - ao ser chamado a SP, caso ocorra a exceção, seja gravado o erro em uma
ECdON> tabela e seja apresentado a texto da exceção.
ECdON> - Ao ser dado o COMMIT, o erro é gravado na tabela.

ECdON> O que está acontecendo é:
ECdON> -- A ser disparado um exception, a SP termina e devolve a mensagem do
ECdON> exception, SEM EXECUTAR O INSERT (apesar de ser feito o commit);

ECdON> Se é comentado o EXCEPTION que está dentro do WHEN any do, é inserido o
ECdON> registro, Mas NÃO É DEVOLVIDO O ERRO!
ECdON> Abaixo o codigo da SP.

ECdON> Edgard


ECdON> CREATE OR ALTER PROCEDURE P_TEST(
ECdON>     TEMP SMALLINT)
ECdON> AS
ECdON> begin
ECdON>   begin
ECdON>      if (TEMP < 0) then
ECdON>         exception EXC_ERROR 'VARIABLE < ZERO';

ECdON>      if (exists (select * from COUNTRIES WHERE ID = '111')) then
ECdON>        update COUNTRIES set NAME = 'VARIABLE OK.' where ID = '111';
ECdON>      else
ECdON>        insert into COUNTRIES (ID, NAME) values ('111','VARIABLE OK.');

ECdON>      when any do
ECdON>      begin
ECdON>         if (exists (select * from COUNTRIES WHERE ID = '111')) then
ECdON>           update COUNTRIES set NAME = 'VARIABLE < ZERO' where ID = '111';
ECdON>         else
ECdON>           insert into COUNTRIES (ID, NAME) values ('111','VARIABLE < ZERO');
ECdON>         exception EXC_ERROR ' OUTRO VARIABLE < ZERO';
ECdON>      end -- when any do
ECdON>   end
ECdON> end



ECdON> 2009/2/4 Gustavo Moda <gustavo.moda em gmail.com>

>> Qual mensagem de erro?
>> Rodei o script em um banco de dados e funcionou corretamente.
>>
>> ______________________________________________
>> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
>> Para saber como gerenciar/excluir seu cadastro na lista, use:
>> http://www.firebase.com.br/fb/artigo.php?id=1107
>> Para consultar mensagens antigas: http://firebase.com.br/pesquisa
>>
ECdON> ______________________________________________
ECdON> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
ECdON> Para saber como gerenciar/excluir seu cadastro na lista, use:
ECdON> http://www.firebase.com.br/fb/artigo.php?id=1107
ECdON> Para consultar mensagens antigas: http://firebase.com.br/pesquisa





Mais detalhes sobre a lista de discussão lista