variáveis/Sessão MySQL

Forum sobre SQL.

Moderador: Moderadores

Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

variáveis/Sessão MySQL

Mensagem por JoséQuintas »

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 )
      :ExecuteCmd()
      :cSQL := "SET @PRENOT = NULL"
      :ExecuteCmd()
      :cSQL := "SET @VALADI = NULL"
      :ExecuteCmd()
Uso a conexão sempre aberta.
Reparei que ao criar as variáveis @PRENOT e @VALADI, elas continuam existindo.
Precisa se preocupar com isso?
Existe algum comando pra apagar tudo de uma vez?
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

variáveis/Sessão MySQL

Mensagem por JoséQuintas »

Aproveitando...

Justamente por causa das variáveis continuarem existindo, é bom tomar cuidado ao usar variáveis não inicializadas.
Dependendo do caso, pode ser necessário primeiro atribuir um valor inicial.

NÃO SEI o que vai acontecer em multithread, que aproveita a mesma conexão.
Se considerar que é mesma sessão, uma thread pode mexer com os valores da outra.
Isso já não vai acontecer com stored procedure e variáveis locais.

Comparando.....
É como se as variáveis @variavel fossem PUBLIC
Tem a vantagem de passá-las entre comandos, mas que pode se tornar desvantagem, no caso de comandos simultâneos.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

variáveis/Sessão MySQL

Mensagem por JoséQuintas »

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.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder