[firebase-br] SQL Doido

Gladiston Santana gladiston em vidy.com.br
Segunda Junho 21 10:02:38 -03 2021


Ok,
Algo que devem ter reportado é que voce usou o mesmo parametro duas vezes:
             ParamByName('*vardataI*').AsDate
 :=dtpPeriodoColeta1.Date;
             ParamByName('*vardataI*').AsDate
 :=dtpPeriodoColeta2.Date;
Talvez tenha copiado errado para o email, mas seu principal erro tá aí.
Algo que você talvez não esteja enxergando é que ao trabalhar com datas
deve-se ter cuidado se sua definição de tabela o campo está como date ou
timestamp, não apenas no FB, mas em qualquer banco de dados isso faz
diferença ao montar uma querie pois um between ou mesmo <= e >= pode ter
resultados omissos, pois between '01.01.2021' and '31.12.2021' para um
timestamp é coisa diferente de date, pois sem o cast será interpretado
como  '01.01.2021 00:00:00' and '31.12.2021 00:00:00' e daí os dados do dia
31.12.2021 vão ser omitidos. Corrija para:
 and cast(v.data_coleta as date) between :vardatai and :vardataf
Uma outra observação é sobre o prepare, você tá preparando a querie todas
as vezes e isso disperdiça muito tempo, você deve fazê-lo (no seu caso)
assim que existe a confirmação dos parametros necessários preenchidos pelo
usuario no formulário e daí então
// faça isso assim que o form se abre ou num botão de "Próximo".
try
 (...codigo para construir a querie)
 if  not qryColetasAgrup.Prepared then
  qryColetasAgrup.Prepare;
except
end

// Daí apenas no momento de execução da querie:
 if  not qryColetasAgrup.Active then
   qryColetasAgrup.Close;
// Eventualmente você pode testar se já foi preparado antes e repreparar,
dependendo do componente de dados após a primeira execução um prepare pode
ser desarmado:
 if  not qryColetasAgrup.Prepared then
  qryColetasAgrup.Prepare;
// Nota: Se vai executar apenas uma vez, não faz sentido preparar, o
prepare só faz sentido se houver multiplas execuções seguidas talvez
mudando alguns parametros, muito util para processos em batch/loop, mas um
desperdício para maior parte de relatórios que são vistos/impressos e
depois descartados.
// Dai você envia os parametros
ParamByName('varCodCliente').Value:=qryBuscaCOD_CLIENTE.AsInteger;
ParamByName('vardatai').Value:= dtpPeriodoColeta1.Date;
ParamByName('vardataf').Value:= dtpPeriodoColeta2.Date  ;

Reveja as considerações acima e se tiver muito lento ao invés de queries
derivativas tente uma CTE.
Uma procedure selecionável é mais fácil de resolver muitos problemas, mas
não será tão performática se você mantêm a mesma querie a levando para
dentro de uma procedure, você só usa uma procedure selecionável se você
tiver um método mais eficiente de obter informações quebrando processos
menores e se não der certo não desanime, já tive coisas que lavavam - não
estou mentindo - 1h para processar que caiu para 2s apenas porque a querie
foi montada de jeito diferente dentro dum programa. E não sou excepcional,
é que o Delphi tem jeitos faceis de fazer as coisas que o camarada faz que
podem fazer dezenas de jeitos diferentes se vocÊ pensar mais tempo e hoje
muita gente pensa em como resolver e não em otimizar.


Mais detalhes sobre a lista de discussão lista