Otimizar rotina

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

Otimizar rotina

Mensagem por JoséQuintas »

Código: Selecionar todos

DECLARE nCursorEOF, nIDBANCARIO, nId, nOrdem INT(11) DEFAULT 0;
DECLARE cBACONTA, cBAAPLIC, cBAIMPSLD, cConta, cAplic, cImpSld VARCHAR(20) DEFAULT 'X';
DECLARE dBADATBAN, dBADATEMI, dDatBan, dDatEmi DATE;
DECLARE nBAVALOR, nBASALDO, nSaldo DECIMAL(16,2);
DECLARE SP_CURSOR CURSOR FOR
   SELECT IDBANCARIO, BACONTA, BAAPLIC, BADATBAN, BADATEMI, BAVALOR, BASALDO, BAIMPSLD, IF( BAVALOR > 0, 1, 2 ) AS ORDEM
   FROM JPBANCARIO
   ORDER BY BACONTA, BAAPLIC, BADATBAN, BADATEMI, ORDEM, IDBANCARIO;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET nCursorEOF = 1;

OPEN SP_CURSOR;
THIS:WHILE nCursorEOF <> 1 DO
   FETCH SP_CURSOR INTO nIDBANCARIO, cBACONTA, cBAAPLIC, dBADATBAN, dBADATEMI, nBAVALOR, nBASALDO, cBAIMPSLD, nOrdem;
   IF nCursorEOF = 1 THEN
      LEAVE THIS;
   END IF;
   IF cBACONTA <> cConta OR cBAAPLIC <> cAplic THEN
      SET nSaldo = 0;
      UPDATE JPBANCARIO SET BAIMPSLD = 'S' WHERE IDBANCARIO = nId;
   END IF;
   SET nSaldo = nSaldo + nBAVALOR;
   IF nBASALDO <> nSaldo OR cBAIMPSLD <> 'N' THEN
      UPDATE JPBANCARIO SET BASALDO = nSaldo, BAIMPSLD = 'N' WHERE IDBANCARIO = nIDBANCARIO;
   END IF;
   IF dDatBan <> dBADATBAN OR ( dBADATBAN = '2999-12-31' AND dDatEmi <> dBADATEMI ) THEN
      UPDATE JPBANCARIO SET BAIMPSLD = 'S' WHERE IDBANCARIO = nId;
   END IF;
   SET cConta = cBACONTA;
   SET nID = nIDBANCARIO;
   SET cAplic = cBAAPLIC;
   SET dDatBan = dBADATBAN;
   SET dDatEmi = dBADATEMI;
END WHILE;
Essa rotina está muito demorada, para movimentação grande, por exemplo de 2008 pra cá.
Por enquanto, uma primeira idéia é separar em duas, uma pegando nome das contas, e outra fazendo o recálculo só daquela conta.
É o recálculo do extrato bancário, com totalização por lançamento, mas visualizando apenas saldo nos totais do dia.
Talvez uma mais complexa seja salvar saldo somente aonde vai ter visualização, se for esse o motivo da demora.
Alguma idéia ?

Outra idéia... talvez limpeza do banco, o que pode ou não ser interessante.
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

Otimizar rotina

Mensagem por JoséQuintas »

Faltou eu dizer:

Vou dividir em duas, não pra ficar mais rápido, mas pra ter a opção de só recalcular uma única conta.
Não achei uma forma de deixar o SELECT opcional na mesma procedure.
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/
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Otimizar rotina

Mensagem por alxsts »

Olá!

Creio que a lentidão se deva ao uso de cursores, que normalmente são mais lentos. O ideal seria fazer o update diretamente, talvez criando uma tabela auxiliar com as movimentações.
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Otimizar rotina

Mensagem por JoséQuintas »

Nem é questão de cursor.
Acho que o SQL é pra fazer operação com tabelas, o que não significa fazer um campo de cada vez, mas sim, 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/
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Otimizar rotina

Mensagem por alxsts »

Olá!
JoséQuintas escreveu:Acho que o SQL é pra fazer operação com tabelas, o que não significa fazer um campo de cada vez, mas sim, tudo de uma vez.
Exatamente o que eu quis dizer...
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Otimizar rotina

Mensagem por JoséQuintas »

Vou rever a anterior, que NÃO É stored.

Código: Selecionar todos

FUNCTION BARecalcula( mbaConta, lRecalculoGeral )

   LOCAL aContaList := {}, oConta, cSQLA, cSQLB, cSQLC, cSQLD
   LOCAL cnSQL := ADOClass():New( AppConexao() )

   hb_Default( @lRecalculoGeral, .F. )
   IF ! lRecalculoAuto .AND. ! lRecalculoGeral
      RETURN NIL
   ENDIF
   WITH OBJECT cnSQL
      :cSQL := "SELECT DISTINCT BACONTA, BAAPLIC" + ;
         " FROM JPBANCARIO" + ;
         iif( mbaConta == NIL, "", " WHERE BACONTA = " + StringSQL( mbaConta ) )
      :Execute()
      DO WHILE ! :Eof()
         AAdd( aContaList, { :String( "BACONTA" ), :String( "BAAPLIC" ) } )
         :MoveNext()
      ENDDO
      FOR EACH oConta IN aContaList
         :ExecuteCmd( "SET @SOMA = 0" )
         :ExecuteCmd( "UPDATE JPBANCARIO" + ;
            " INNER JOIN" + ;
            "( SELECT IDBANCARIO, BADATBAN, BADATEMI, BAVALOR," + ;
            " BASALDO, IF( BAVALOR < 0, 2, 1 ) AS ORDEM, @SOMA := @SOMA + BAVALOR AS SALDO" + ;
            " FROM JPBANCARIO" + ;
            " WHERE BACONTA = " + StringSQL( oConta[ 1 ] ) + ;
            " AND BAAPLIC = " + StringSQL( oConta[2 ] ) + ;
            " ORDER BY BACONTA, BAAPLIC, BADATBAN, BADATEMI, ORDEM, IDBANCARIO ) AS A" + ;
            " ON JPBANCARIO.IDBANCARIO = A.IDBANCARIO" + ;
            " SET JPBANCARIO.BASALDO = A.SALDO" + ;
            " WHERE JPBANCARIO.BACONTA = " + StringSQL( oConta[ 1 ] ) + " AND JPBANCARIO.BASALDO <> A.SALDO" )
      NEXT
      :ExecuteCmd( "SET @SOMA = NULL" )
      :ExecuteCmd( "SET @A = 0" )
      :ExecuteCmd( "SET @B = 0" )
      cSQLA := " SELECT BACONTA, BAAPLIC, IDBANCARIO, BADATBAN, BADATEMI," + ;
         " IF( BAVALOR < 0, 2, 1 ) AS ENTSAI, @A := @A + 1 AS ORDEM" + ;
         " FROM JPBANCARIO" + ;
         " ORDER BY BACONTA, BAAPLIC, BADATBAN, ENTSAI, BADATEMI, IDBANCARIO"
      cSQLB := " SELECT BACONTA, BAAPLIC, IDBANCARIO, BADATBAN, BADATEMI," + ;
         " IF( BAVALOR < 0, 2, 1 ) AS ENTSAI, @B := @B + 1 AS ORDEM" + ;
         " FROM JPBANCARIO" + ;
         " ORDER BY BACONTA, BAAPLIC, BADATBAN, ENTSAI, BADATEMI, IDBANCARIO"
      cSQLC := " SELECT BACONTA, BAAPLIC, BADATBAN, MAX( ORDEM ) AS MAXIMO" + ;
         " FROM ( " + cSQLB + " ) AS B" + ;
         " GROUP BY BACONTA, BAAPLIC, BADATBAN"
      cSQLD := " SELECT IDBANCARIO FROM" + ;
         " ( " + cSQLA + " ) AS A" + ;
         " INNER JOIN" + ;
         " ( " + cSQLC + " ) AS C" + ;
         " ON A.ORDEM = C.MAXIMO"
      :ExecuteCmd( " UPDATE JPBANCARIO" + ;
         " LEFT JOIN ( " + cSQLD + " ) AS D" + ;
         " ON JPBANCARIO.IDBANCARIO = D.IDBANCARIO" + ;
         " SET BAIMPSLD = IF( JPBANCARIO.IDBANCARIO = D.IDBANCARIO, 'S', 'N' )" + ;
         " WHERE BAIMPSLD <> IF( JPBANCARIO.IDBANCARIO = D.IDBANCARIO, 'S', 'N' )" )
      :ExecuteCmd( "SET @A = NULL" )
      :ExecuteCmd( "SET @B = NULL" )
      :CloseRecordset()
   ENDWITH

   RETURN .T.
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

Otimizar rotina

Mensagem por JoséQuintas »

Misturei com XML, até que tá interessante, pelo menos não enche de arquivos.

Código: Selecionar todos

[ze_bancariocalcula]
CREATE PROCEDURE ze_bancarioCalcula()

BEGIN

DECLARE nCursorEOF INT(11) DEFAULT 0;
DECLARE cConta VARCHAR(20) DEFAULT 'X';
DECLARE SP_CURSOR CURSOR FOR
   SELECT DISTINCT BACONTA
   FROM JPBANCARIO
   ORDER BY BACONTA;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET nCursorEOF = 1;
OPEN SP_CURSOR;
THIS:WHILE nCursorEOF <> 1 DO
   FETCH SP_CURSOR INTO cConta;
   IF nCursorEOF = 1 THEN
      LEAVE THIS;
   END IF;
   CALL ze_bancarioCalculaConta( cConta );
END WHILE;

END
[/ze_bancariocalcula]

[ze_bancariocalculaconta]
CREATE PROCEDURE ze_bancariocalculaConta( cConta VARCHAR(20) )

BEGIN

DECLARE nCursorEOF, nIDBANCARIO, nId, nOrdem INT(11) DEFAULT 0;
DECLARE cBAAPLIC, cBAIMPSLD, cAplic, cImpSld VARCHAR(20) DEFAULT 'X';
DECLARE dBADATBAN, dBADATEMI, dDatBan, dDatEmi DATE;
DECLARE nBAVALOR, nBASALDO, nSaldo DECIMAL(16,2);
DECLARE SP_CURSOR CURSOR FOR
   SELECT IDBANCARIO, BAAPLIC, BADATBAN, BADATEMI, BAVALOR, BASALDO, BAIMPSLD, IF( BAVALOR > 0, 1, 2 ) AS ORDEM
   FROM JPBANCARIO
   WHERE BACONTA = cConta
   ORDER BY BAAPLIC, BADATBAN, BADATEMI, ORDEM, IDBANCARIO;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET nCursorEOF = 1;

OPEN SP_CURSOR;
THIS:WHILE nCursorEOF <> 1 DO
   FETCH SP_CURSOR INTO nIDBANCARIO, cBAAPLIC, dBADATBAN, dBADATEMI, nBAVALOR, nBASALDO, cBAIMPSLD, nOrdem;
   IF nCursorEOF = 1 THEN
      LEAVE THIS;
   END IF;
   IF cBAAPLIC <> cAplic THEN
      SET nSaldo = 0;
      UPDATE JPBANCARIO SET BAIMPSLD = 'S' WHERE IDBANCARIO = nId;
   END IF;
   SET nSaldo = nSaldo + nBAVALOR;
   IF nBASALDO <> nSaldo OR cBAIMPSLD <> 'N' THEN
      UPDATE JPBANCARIO SET BASALDO = nSaldo, BAIMPSLD = 'N' WHERE IDBANCARIO = nIDBANCARIO;
   END IF;
   IF dDatBan <> dBADATBAN OR ( dBADATBAN = '2999-12-31' AND dDatEmi <> dBADATEMI ) THEN
      UPDATE JPBANCARIO SET BAIMPSLD = 'S' WHERE IDBANCARIO = nId;
   END IF;
   SET nID = nIDBANCARIO;
   SET cAplic = cBAAPLIC;
   SET dDatBan = dBADATBAN;
   SET dDatEmi = dBADATEMI;
END WHILE;

END
[/ze_bancariocalculaconta]

[ze_bancorecalcula]
FUNCTION BARecalcula( mbaConta, lRecalculoGeral )

   LOCAL aContaList := {}, oConta, cSQLA, cSQLB, cSQLC, cSQLD
   LOCAL cnSQL := ADOClass():New( AppConexao() )

   hb_Default( @lRecalculoGeral, .F. )
   IF ! lRecalculoAuto .AND. ! lRecalculoGeral
      RETURN NIL
   ENDIF
   WITH OBJECT cnSQL
      :cSQL := "SELECT DISTINCT BACONTA, BAAPLIC" + ;
         " FROM JPBANCARIO" + ;
         iif( mbaConta == NIL, "", " WHERE BACONTA = " + StringSQL( mbaConta ) )
      :Execute()
      DO WHILE ! :Eof()
         AAdd( aContaList, { :String( "BACONTA" ), :String( "BAAPLIC" ) } )
         :MoveNext()
      ENDDO
      FOR EACH oConta IN aContaList
         :ExecuteCmd( "SET @SOMA = 0" )
         :ExecuteCmd( "UPDATE JPBANCARIO" + ;
            " INNER JOIN" + ;
            "( SELECT IDBANCARIO, BADATBAN, BADATEMI, BAVALOR," + ;
            " BASALDO, IF( BAVALOR < 0, 2, 1 ) AS ORDEM, @SOMA := @SOMA + BAVALOR AS SALDO" + ;
            " FROM JPBANCARIO" + ;
            " WHERE BACONTA = " + StringSQL( oConta[ 1 ] ) + ;
            " AND BAAPLIC = " + StringSQL( oConta[2 ] ) + ;
            " ORDER BY BACONTA, BAAPLIC, BADATBAN, BADATEMI, ORDEM, IDBANCARIO ) AS A" + ;
            " ON JPBANCARIO.IDBANCARIO = A.IDBANCARIO" + ;
            " SET JPBANCARIO.BASALDO = A.SALDO" + ;
            " WHERE JPBANCARIO.BACONTA = " + StringSQL( oConta[ 1 ] ) + " AND JPBANCARIO.BASALDO <> A.SALDO" )
      NEXT
      :ExecuteCmd( "SET @SOMA = NULL" )
      :ExecuteCmd( "SET @A = 0" )
      :ExecuteCmd( "SET @B = 0" )
      cSQLA := " SELECT BACONTA, BAAPLIC, IDBANCARIO, BADATBAN, BADATEMI," + ;
         " IF( BAVALOR < 0, 2, 1 ) AS ENTSAI, @A := @A + 1 AS ORDEM" + ;
         " FROM JPBANCARIO" + ;
         " ORDER BY BACONTA, BAAPLIC, BADATBAN, ENTSAI, BADATEMI, IDBANCARIO"
      cSQLB := " SELECT BACONTA, BAAPLIC, IDBANCARIO, BADATBAN, BADATEMI," + ;
         " IF( BAVALOR < 0, 2, 1 ) AS ENTSAI, @B := @B + 1 AS ORDEM" + ;
         " FROM JPBANCARIO" + ;
         " ORDER BY BACONTA, BAAPLIC, BADATBAN, ENTSAI, BADATEMI, IDBANCARIO"
      cSQLC := " SELECT BACONTA, BAAPLIC, BADATBAN, MAX( ORDEM ) AS MAXIMO" + ;
         " FROM ( " + cSQLB + " ) AS B" + ;
         " GROUP BY BACONTA, BAAPLIC, BADATBAN"
      cSQLD := " SELECT IDBANCARIO FROM" + ;
         " ( " + cSQLA + " ) AS A" + ;
         " INNER JOIN" + ;
         " ( " + cSQLC + " ) AS C" + ;
         " ON A.ORDEM = C.MAXIMO"
      :ExecuteCmd( " UPDATE JPBANCARIO" + ;
         " LEFT JOIN ( " + cSQLD + " ) AS D" + ;
         " ON JPBANCARIO.IDBANCARIO = D.IDBANCARIO" + ;
         " SET BAIMPSLD = IF( JPBANCARIO.IDBANCARIO = D.IDBANCARIO, 'S', 'N' )" + ;
         " WHERE BAIMPSLD <> IF( JPBANCARIO.IDBANCARIO = D.IDBANCARIO, 'S', 'N' )" )
      :ExecuteCmd( "SET @A = NULL" )
      :ExecuteCmd( "SET @B = NULL" )
      :CloseRecordset()
   ENDWITH

   RETURN .T.
[/ze_bancorecalcula]
Nota: alterei o maior/menor pro site não cortar.

Nota2: Com certeza o último ainda é PRG, mas no XML tanto faz.
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

Otimizar rotina

Mensagem por JoséQuintas »

Acho que encontrei o erro na rotina.

Código: Selecionar todos

select x, @soma := @soma + valor ... order by ....
A questão é:
precisa primeiro colocar em ordem, pra depois fazer as contas.
do jeito que está.... vai fazer as contas em qualquer ordem, e depois colocar em ordem.
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

Otimizar rotina

Mensagem por JoséQuintas »

Dividi em tres.
Menos coisas pra analizar por vez.

o geral, que pega cada conta

Código: Selecionar todos

CREATE PROCEDURE ze_bancarioCalcula()

BEGIN

DECLARE nCursorEOF INT(11) DEFAULT 0;
DECLARE cConta VARCHAR(20) DEFAULT 'X';
DECLARE SP_CURSOR CURSOR FOR
   SELECT DISTINCT BACONTA
   FROM JPBANCARIO
   ORDER BY BACONTA;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET nCursorEOF = 1;
OPEN SP_CURSOR;
THIS:WHILE nCursorEOF <> 1 DO
   FETCH SP_CURSOR INTO cConta;
   IF nCursorEOF = 1 THEN
      LEAVE THIS;
   END IF;
   CALL ze_bancarioCalculaConta( cConta );
END WHILE;

END
o da conta, que pega aplicação ou não

Código: Selecionar todos

CREATE PROCEDURE ze_bancarioCalculaconta( cConta VARCHAR(20) )

BEGIN

DECLARE nCursorEOF INT(11) DEFAULT 0;
DECLARE cAplicacao VARCHAR(1) DEFAULT 'X';
DECLARE SP_CURSOR CURSOR FOR
   SELECT DISTINCT BAAPLIC
   FROM JPBANCARIO
   WHERE BACONTA = cConta;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET nCursorEOF = 1;
OPEN SP_CURSOR;
THIS:WHILE nCursorEOF <> 1 DO
   FETCH SP_CURSOR INTO cAplicacao;
   IF nCursorEOF = 1 THEN
      LEAVE THIS;
   END IF;
   CALL ze_bancarioCalculaContaAplicacao( cConta, cAplicacao );
END WHILE;

END
e o que trata uma única conta/aplicação

Código: Selecionar todos

CREATE PROCEDURE ze_BancarioCalculaContaAplicacao( cConta VARCHAR(20), cAplicacao VARCHAR(1) )

BEGIN

SET @nSoma = 0.00;

UPDATE JPBANCARIO
INNER JOIN
   ( SELECT A.IDBANCARIO, @nSoma := @nSoma + A.BAVALOR AS SALDO
      FROM
      ( SELECT IDBANCARIO, BADATBAN, BADATEMI, BAVALOR,
         IF( BAVALOR < 0, 2, 1 ) AS ORDEM
      FROM JPBANCARIO
      WHERE BACONTA = cConta AND BAAPLIC = cAplicacao
      ORDER BY BADATBAN, BADATEMI, ORDEM, IDBANCARIO
      ) AS A
   ) AS B
ON JPBANCARIO.IDBANCARIO = B.IDBANCARIO
SET JPBANCARIO.BASALDO = B.SALDO;

SET @dBanco = '2998-12-31';
SET @dEmissao = '2998-12-31';
UPDATE JPBANCARIO
INNER JOIN
   ( SELECT A.IDBANCARIO, IF( A.BADATBAN <> @dBanco OR ( A.BADATBAN = '2999-12-31' AND A.BADATEMI <> @dEmissao ), 'S', 'N' ) AS IMPSALDO, @dBanco := A.BADATBAN, @dEmissao := A.BADATEMI
     FROM
     ( SELECT IDBANCARIO, BADATBAN, BADATEMI, IF( BAVALOR < 0, 2, 1 ) AS ENTSAI
       FROM JPBANCARIO
       WHERE BACONTA = cConta AND BAAPLIC = cAplicacao
       ORDER BY BADATBAN DESC, ENTSAI DESC, BADATEMI DESC, IDBANCARIO DESC
     ) AS A
   ) AS B ON JPBANCARIO.IDBANCARIO = B.IDBANCARIO
SET JPBANCARIO.BAIMPSLD = B.IMPSALDO;

END
Se eu quiser recálculo geral: ze_BancarioCalcula()
Se eu quiser uma conta: ze_BancarioCalculaConta( "conta" )
Se eu quiser o detalhe: ze_BancarioCalculaContaAplicacao( "conta", "S" )

No final, acho que tem que ser por aí, porque quanto menor as rotinas, facilita pesquisar problema.
Mesmo que desse pra juntar tudo numa só, qualquer erro implica em olhar a rotina inteira, então melhor dividir ao máximo "por assunto".
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