[firebase-br] Trigger : Do instead

Adriano dos Santos Fernandes adrianosf em uol.com.br
Qua Ago 27 07:52:09 -03 2008


Mário Reis escreveu:
> Ainda relativo a um "Estorno"
> 
> Tanto quanto me lembro no Oracle e no PostGres temos qq coisa como "Do instead 
> of..." DELETE. Aqui não de forma que pus-me a inventar qual a melhor forma de
> eliminar uma linha sem ralmente a eliminar,i.e., fazendo insert de uma nova
> c/valores*-1
>  
> /*1.ºo registo acabado de eliminar para para Tabela de Historico */
> Insert into <Historico_T1> (Campo_ID1....,Val1,Val2,Val3, Sign, Status, Visible)
> Values(OLD.Field_ID1,....Old.Val1,Old.Val2,Old.Val3,'+','INS', 'Y')
>  
> /*2.ºht Insert do Velho simulando que realmente não foi apagado */
> Insert into <Tabela_T1> (Campo_ID1....,Val1,Val2,Val3, Sign, Status)
> Values(OLD.Field_ID1,....Old.Val1,Old.Val2,Old.Val3,'+','EST','N')
>  
> Insert into <Tabela_T1> (Campo_ID1....,Val1,Val2,Val3, Sign, Status)
> Values(OLD.Field_ID1,....Old.Val1*-1,Old.Val2*-1,Old.Val3*-1,'-','EST','N')
>  
> E, funciona bem a maioria das vezes, c/ o resultado pretendido:
> Velho a passar para Historico:
> ==============================================================================
>  ID  |        Val1  |        Val2  |        Val3  | Sign  |   Status | Visible
> ==============================================================================
> 200 |      35,00  |     135,00  |     335,00  |      +    |   'INS'   |  YES
>  
> Novos registos:
> ==============================================================================
>  ID  |      Val1  |        Val2  |        Val3  |   Sign  |   Status |Visible
> ==============================================================================
> 200 |      35,00  |     135,00  |     335,00  |      +    |   'EST'   |  NO
> 200 |    -35,00  |     -135,00  |    -335,00  |      -    |   'EST'   |  NO
> Perfeito até aqui.
> Só que às vezes inexplicavelmente repetem-se
> (Chave Unica Inactiva/doutro modo levanta-se a excepção e rollback...)
> ===============================================================================
>  ID  |        Val1  |        Val2  |        Val3  |   Sign  |   Status | Visible
> ===============================================================================
> 200 |     35,00  |     135,00  |     335,00  |      +    |   'EST'   |  NO
> 200 |    -35,00  |    -135,00  |    -335,00  |      -    |   'EST'   |  NO
> 200 |     35,00  |     135,00  |     335,00  |      +    |   'EST'   |  NO
> 200 |    -35,00  |    -135,00  |    -335,00  |      -    |   'EST'   |  NO
> 200 |     35,00  |     135,00  |     335,00  |      +    |   'EST'   |  NO
> 200 |    -35,00  |    -135,00  |    -335,00  |      -    |   'EST'   |  NO
> 200 |     35,00  |     135,00  |     335,00  |      +    |   'EST'   |  NO
> 200 |    -35,00  |    -135,00  |    -335,00  |      -    |   'EST'   |  NO
>  
> Alguma ideia? Obrigado

O problema é causado porque os registros novos são lidos pelo FOR. Se o 
seu ID não se repetisse, vc poderia verificar o maior ID antes de 
começar o FOR. No seu caso, vc pode resolver de duas maneiras:
1) Usando uma tabela temporária para ler todos os registros antes de 
começar inserir;
2) Forçando o FOR a ser ordenado através de um SORT. Dê um ORDER BY por 
algum campo que não tenha índice. É uma solução meio gambiarrística, mas 
é o modo correto que o FB deveria se comportar.


Adriano





Mais detalhes sobre a lista de discussão lista