Tô pensando até na hipótese de complicar, por ficar na dúvida sobre essas variáveis.
Código: Selecionar todos
:cSQL := "UPDATE JPITPED" + ;
" JOIN JPPEDIDO ON JPPEDIDO.IDPEDIDO = JPITPED.IPPEDIDO" + ;
" SET IPVALADI = ( @VALADI := ROUND( JPPEDIDO.PDVALADI / IF( PDVALPRO = 0, 1, PDVALPRO) * ( JPITPED.IPPREPED * JPITPED.IPQTDE ), 2 ) )," + ;
" JPITPED.IPPRENOT = ( @PRENOT := ROUND( IF( IPQTDE = 0, 0, ( ( JPITPED.IPPREPED + @VALADI ) * JPITPED.IPQTDE )" + ;
" * ( ( 100 - JPPEDIDO.PDPERDES ) / 100 ) * ( ( 100 + JPPEDIDO.PDPERADI ) / 100 )" + ;
" / IF( JPITPED.IPQTDE = 0, 1, JPITPED.IPQTDE ) ), 5 ) )," + ;
" IPVALPRO = @PRENOT * IPQTDE" + ;
" WHERE JPITPED.IPPEDIDO = " + NumberSQL( nIdPedido )
Algo do tipo: um SELECT para o cálculo do valor adicional, depois um SELECT encima para o cálculo do valor pra nota, depois um SELECT encima para o valor do produto, e finalmente um UPDATE de tudo.
Código: Selecionar todos
UPDATE JPITPED
JOIN
( SELECT *,
PRENOT * IPQTDE AS VALPRO
FROM
( SELECT
*,
ROUND( IF( IPQTDE = 0, 0, ( ( IPPREPED + @VALADI ) * IPQTDE )" + ;
" * ( ( 100 - PDPERDES ) / 100 ) * ( ( 100 + PDPERADI ) / 100 )" + ;
" / IF( IPQTDE = 0, 1, IPQTDE ) ), 5 ) ) AS PRENOT
FROM
( SELECT
IPQTDE,
IPPREPED,
PDPERDES,
PDPERADI,
ROUND( JPPEDIDO.PDVALADI / IF( PDVALPRO = 0, 1, PDVALPRO) * ( JPITPED.IPPREPED * JPITPED.IPQTDE ), 2 ) ) AS VALADI
FROM JPITPED WHERE IPPEDIDO = nIdPedido
) AS A
) AS B
) AS C
SET
IPVALADI = VALADI,
IPPRENOT = PRENOT,
IPVALPRO = PRENOT * IPQTDE
WHERE IPPEDIDO = nIdPedido
É muita complicação comparado ao anterior, mas... pelo menos não tem variável que possa causar interferência
Ou então...
Fazer com @variavel mesmo, e após os testes gravar como STORED PROCEDURE apenas trocando pra variável local.
Menos risco de fazer coisa errada.
É... porque se errar num dos filtros, pode atualizar registros demais, ou somar registros demais.
Outra saída é dividir em 3 comandos, atualizar um campo de cada vez.
Pois é...
Não adianta resolver com um único comando, se depois pra fazer manutenção ficar complicado.