[firebase-br] Recalculo de saldo (Trigger)

Fabiano Lima frguitar em bol.com.br
Seg Set 26 12:03:47 -03 2011


Cara, nem sei como te agradecer, valew mesmo.

Só uma coisinha no final, a atualização posterior  retorna o saldo anterior dela mesma + o credito, não teria de ser o saldo anterior da linha anterior?

ex:
saldo_ini = 100

apos inserir dados

lanc_id credito debito saldo
1         1        0      101
2         1        0      102
3         1        0      103

após o update na linha no id 2

lanc_id credito debito saldo
1         1        0      101
2         10      0       113
3         1        0      104



att
Fabiano
 


____________________________________________

Em 26/09/2011 10:28, andre conrado < acf.andre em gmail.com > escreveu:
Ok amigo, seu problema é de lógica, então vamos a ela:

Na sua TRIGGER o primeiro passo está correto, isto é, vc obtém o saldo
somando as colunas a CREDITO, DEBITO e SALDO_INI. Até está razoável,
mas eu faria um diferente, pense o seguinte:

- Quanto o primeiro lançamento for inserido ou alterado o campo saldo
este lançamento precisa ser atualizado, o que não ocorre em seu
código, já que o FOR SELECT só está tratando os registros posteriores.
 Então está faltando depois dos SELECTs de somatório o seguinte linha:
 NEW.SALDO = BANCOSALDO + NEW.CREDITO - NEW.DEBITO;
 (Imagino o campo SALDO não esteja sendo calculado via aplicação)

Vamos agora ao conteúdo do FOR SELECT:

1º - Sua rotina está colocando no SALDO o valor total dos créditos e
débitos até o lançamento atual, isso desconsidera os créditos e
débitos posteriores que interferem nos cálculos posteriores.
2º - Quanto o UPDATE é executado uma nova chamada a TRIGGER será
gerada, o que fará com que nova chamada seja gerada até que não acha
mais lançamento. Sendo assim, as atualização não precisariam ser
chamadas dentro de um FOR SELECT.

Tá ficando confuso néh, fiz está colocações para complexidade do
rotina acima, então vamos começar todo de novo. Tente assim, e me diga
se funciona:

// TRIGGER para Atualiza do SALDO atual

CREATE OR ALTER trigger trg_saldo_up_before for lanc
active after before position 2

AS
DECLARE VARIABLE LANCAMENTO INTEGER;
DECLARE VARIABLE SALDOANTERIOR INTEGER;

BEGIN

 /* Primeiro passo, obter o saldo anterior, se existirem
lançamentos anteriores então obtenho o saldo do último lançamento
 caso contrário obtenho o saldo inicial do banco */

 IF (EXISTS(SELECT 0 FROM LANC WHERE LANC_ID <  NEW.LANC_ID)) THEN
 SELECT FIRST 1 SALDO FROM LANC ORDER BY LANC_ID DESC INTO
:SALDOANTERIOR;
 ELSE
 SELECT SALDO_INI FROM CADBANCO WHERE CCONTA = NEW.CCONTA INTO
:SALDOANTERIOR;

 // Calcula o saldo atual

 NEW.SALDO = SALDOANTERIOR + NEW.CREDITO - NEW.DEBITO;

END

// TRIGGER para atualizar o SALDO dos lançamento subsequentes

CREATE OR ALTER trigger trg_saldo_up_after for lanc
active after update position 2

AS
DECLARE VARIABLE LANCAMENTO INTEGER;
DECLARE VARIABLE SALDOANTERIOR INTEGER;

BEGIN

 // Localiza o próximo lançamento

 SELECT FIRST 1 LANC_ID FROM LANC WHERE LANC_ID >  NEW.LANC_ID
ORDER BY LANC_ID INTO :LANCAMENTO;

 // Simula a alteração do próximo lançamento para que o FIREBIRD
gere uma nova chamada a TRIGGER de atualização do SALDO

 UPDATE LANC SET CREDITO = CREDITO WHERE LANC_ID = :LANCAMENTO;

END


Dúvida ou críticas? Não fique com elas... rsrs

abçs

______________________________________________
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





Mais detalhes sobre a lista de discussão lista