Página 1 de 1

Melhorar stored procedure

Enviado: 08 Jun 2022 12:20
por JoséQuintas

Código: Selecionar todos

CREATE PROCEDURE ze_ContabilBalancete( dInicial DATE, dFinal DATE, nFechamento INT(11), nGrau INT(11 ), nFechado INT(11) )

BEGIN

DECLARE dFechamento DATE;
DECLARE nAno, nMes, nFechaOficial INT(11);
DECLARE nDebito, nCredito DECIMAL(16,2);

SET nFechaOficial := ( SELECT GREATEST( COALESCE( EMFECHA, 12 ), 1 ) FROM JPEMPRESA WHERE IDEMPRESA = 1 );

SET nAno := YEAR( dInicial );

SET dFechamento := DATE( CONCAT( LPAD( nAno - 1, 4, '0' ), '-12-31' ) );
IF nFechamento != 12 THEN
   SET nMes := MONTH( dInicial );
   SET nMes := FLOOR( ( nMes - 1 ) / nFechaOficial ) * nFechaOficial;
   IF nMes <> 0 THEN
      SET dFechamento := DATE( CONCAT( LPAD( nAno, 4, '0' ), '-', LPAD( nMes, 2, '0' ), '-01' ) );
      SET dFechamento := DATE( LAST_DAY( dFechamento ) );
   END IF;
END IF;

DROP TEMPORARY TABLE IF EXISTS SALDOS;

CREATE TEMPORARY TABLE SALDOS AS
SELECT CPCODIGO, CPGRUPO,
  ze_ContabilSaldoExercicio( IDCTCONTA, DATE( DATE_ADD( dInicial, INTERVAL -1 DAY ) ), dFechamento ) AS SALDOANTERIOR,
  ze_ContabilSaldoDebito( IDCTCONTA, dInicial, dFinal ) AS SALDOENTRADA,
  ze_ContabilSaldoCredito( IDCTCONTA, dInicial, dFinal ) AS SALDOSAIDA,
  0 AS SALDOATUAL
  FROM JPCTCONTA
  WHERE CPTIPO = 'A';

UPDATE TEMPORARY SALDOS SET SALDOATUAL = SALDOANTERIOR + SALDOENTRADA - SALDOSAIDA;

IF nFechado = 1 THEN
   IF DATE_ADD( dFechamento, INTERVAL nFechaOficial DAY ) = dFinal THEN
      SELECT SUM( SALDOATUAL ) FROM SALDOS WHERE CPGRUPO = 'R' AND SALDOATUAL > 0 INTO nDebito;
      SELECT SUM( SALDOATUAL ) FROM SALDOS WHERE CPGRUPO - 'R' AND SALDOATUAL < 0 INTO nCredito;
      UPDATE TEMPORARY SALDOS SET
         SALDOENTRADA = SALDOENTRADA + nDebito, SALDOSAIDA = SALDOSAIDA + nCredito, SALDOATUAL = SALDOATUAL + nDebito - nCredito
         WHERE CPCODIGO = ( SELECT EMLUCRO FROM JPEMPRESA );
      UPDATE TEMPORARY SALDOS SET SALDOENTRADA = SALDOENTRADA + ABS( SALDOATUAL ), SALDOATUAL = 0
         WHERE CPGRUPO = 'R' AND SALDOATUAL < 0;
      UPDATE TEMPORARY SALDOS SET SALDOSAIDA = SALDOSAIDA + ABS( SALDOATUAL ), SALDOATUAL = 0
         WHERE CPGRUPO = 'R' AND SALDOATUAL > 0;
   END IF;
END IF;

SELECT
   JPCTCONTA.IDCTCONTA, JPCTCONTA.CPCODIGO, JPCTCONTA.CPGRAU, JPCTCONTA.CPTIPO, JPCTCONTA.CPGRUPO,
	JPCTCONTA.CPNOME, SUM( SALDOS.SALDOANTERIOR ) AS ANTERIOR, SUM( SALDOS.SALDOENTRADA ) AS ENTRADA,
   SUM( SALDOS.SALDOSAIDA ) AS SAIDA, SUM( SALDOS.SALDOATUAL ) AS ATUAL
FROM JPCTCONTA
LEFT JOIN SALDOS ON TRIM( JPCTCONTA.CPCODIGO ) = SUBSTR( SALDOS.CPCODIGO, 1, LENGTH( TRIM( JPCTCONTA.CPCODIGO ) ) )
WHERE JPCTCONTA.CPGRAU <= nGrau
GROUP BY JPCTCONTA.IDCTCONTA
HAVING anterior != 0 OR entrada != 0 OR saida != 0
ORDER BY CPCODIGO;

DROP TEMPORARY TABLE SALDOS;

END
Sei lá se dá pra melhorar isso, ainda mais que depende de rotinas externas.

Aproveitando...
Pra quem teima em usar débito/crédito na contabilidade...
Considerando entrada/saída... simplifica demais...

Melhorar stored procedure

Enviado: 08 Jun 2022 12:31
por JoséQuintas
JoséQuintas escreveu:Sei lá se dá pra melhorar isso, ainda mais que depende de rotinas externas.
Faltou dizer:
Está demorando menos de 2 segundos aqui nos testes.
Apesar de serem dados reais, é pouca movimentação.
Não sei qual vai ser o comportamento com muita movimentação.
E não dá pra testar agora, porque por enquanto ajustando o sped contábil que tem prazo.
Faz parte do sped contábil que estou ajustando.
O que não dá pra testar agora é aumentar a movimentação, senão atrapalha finalizar o sped com os dados atuais.

É mais pra alguém que esteja familiarizado com stored procedure/SQL, e possa detectar alguma coisa visível.

Sou principiante nisso ainda, apesar de estar usando e talvez abusando.

Melhorar stored procedure

Enviado: 08 Jun 2022 14:14
por JoséQuintas
Essa rotina vai atender:

- Balancete de período (diário/mensal/anual/qualquer período)
- Balanço Patrimonial
- Demonstração de Resultado
- Sped: Saldos periódicos antes do encerramento
- Sped: Saldos periódicos após encerramento
- Sped: Balanços Patrimoniais
- Sped: Demonstrações de Resultado

Talvez mais interessante remontar a rotina, porque do jeito que está não serve pra comparativos mensais/anuais, a não ser que faça o restante pelo Harbour.

Melhorar stored procedure

Enviado: 09 Jun 2022 01:07
por alxsts
Olá!

Uma boa prática é analisar o plano de execução (SHOW PLAN), além do modelo de dados.

Melhorar stored procedure

Enviado: 09 Jun 2022 11:26
por JoséQuintas
Parece que pra stored procedure não tem isso.
Teria que testar uma parte de cada vez.

Melhorar stored procedure

Enviado: 09 Jun 2022 13:27
por JoséQuintas
Tem um erro na procedure: o ZERO
Acabou criando um campo INT mas precisava de um DECIMAL.
Vou tentar com 0.00, senão vou usar uma variável pra isso.

Melhorar stored procedure

Enviado: 09 Jun 2022 16:19
por JoséQuintas
Estou melhorando muito... removendo erros kkkkk
Por exemplo, o uso de INTERVAL DAY sendo que são meses e não dias.

Melhorar stored procedure

Enviado: 09 Jun 2022 18:24
por alxsts
Olá!
JoséQuintas escreveu:Parece que pra stored procedure não tem isso.
Se fosse um MS SQL Server ou PostgreSQL teria um debugger próprio...

Para MySQL / MariaDB encontrei este Debugger for MySQL. Diz que custa 239 Reais. Tem um botão "Download". Baixei e instalei. Não avisou nada se é versão Trial. Também não pediu número de licença. Abri, conectei ao MariaDB mas não testei o processo de debug...

Melhorar stored procedure

Enviado: 09 Jun 2022 19:55
por JoséQuintas
JoséQuintas escreveu:Faltou dizer:
Está demorando menos de 2 segundos aqui nos testes.
Pequena grande correção:
2 segundos é pra gerar o sped contábil.
Pra isso, essa procedure é executada trocentas vezes, para cada mês, e pra umas 5 ou mais informações.
Talvez 60 vezes em 2 segundos.

É tanto teste, que tô meio maluco aqui.

Melhorar stored procedure

Enviado: 12 Jun 2022 02:01
por JoséQuintas
spedct.png
Finalmente.
Só informação básica faltando.
Então.... stored procedure ok.