[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