Fórum Consulta entre Datas SQL com ADO - Nao Funciona????? #245550
04/08/2004
0
if Opc = ´4´ then
begin
with ADOQuery do
begin
if Active then close;
SQL.Clear;
SQL.Add(´SELECT * FROM Mensagem WHERE Mensagem_DATA BETWEEN (:DtIni) and (:DtFin)´);
Parameters.ParamByName(´DtIni´).Value := Edit1.Text;
Parameters.ParamByName(´DtFin´).Value := Edit2.Text;
Open;
end;
end;
Sendo como acima, eu info DInicial: 02/02/2004 e Final: 03/02/2004
ele estar me retornando todos os registros com data de 03/02/2004, 02/03/2004 e 02/04/2004 e naos os registros do dia 02 e 03 do mês 02 de 2004.
Desde já O B R I G A D O....
Canastra
Curtir tópico
+ 0Posts
04/08/2004
Vinicius2k
Veja esta sequência :
02/02/2004
03/02/2004
02/03/2004
03/03/2004
Se for analizar como data está na ordenação crescente correta não é mesmo? mas como string não está 02/03/2004 é menor que 03/02/2004... Sua consulta pode ficar instavel e as vezes retornar corretamente ou não... vai depender do intervalo que vc passar nos parametros...
Se vc pretende trabalhar com datas em formato string na base sugiro que utilize o tamanho de 8 posições e grave a data invertida e sem barras, apenas desta forma vc terá a ordenação correta, por exemplo :
20040202
20040203
20040302
20040303
Espero ter ajudado...
T+
Gostei + 0
04/08/2004
Canastra
-Referente aos dados estou pedindo que seja retornado os registros de
apenas dois dias: Dia 02 e 03 do mês de FEV/04, e nãos de outros meses
-No parameters.parambyname(´ -- ´).Value eu coloquei (VALUE) pois não me resta outra opçao a nao ser esta.
Por favor agradeço se mandar exemplos, O B R I G A D O..........
Gostei + 0
04/08/2004
Vinicius2k
Vou tentar ser mais claro...
Vc tem os registros com as datas 03/02/2004 , 02/03/2004 e 02/04/2004 correto? é o que vc postou q está tendo de retorno... pois bem... vc solicita um intervalo entre 02/02/2004 e 03/02/2004 e na ordenação por String [b:1ad837fa8b]02/03[/b:1ad837fa8b]/2004 e [b:1ad837fa8b]02/04[/b:1ad837fa8b]/2004 estão neste intervalo...
Nos registros que vc tem, se vc mandar ordenar pelo campo data a ordenação estará assim :
Resumindo : vc não pode usar string em banco de dados para manipulação de datas em seu formato ´amigável´... a única forma de obter o resultado desejado será invertendo e sem as barras como já lhe mostrei... ou usar campos do tipo data.
T+
Gostei + 0
04/08/2004
Canastra
Edit2.Text := ´20040203´;
Parameters.ParamByName(´DtIni´).Value := Edit1.Text;
- Se eu colocar Edit com AAAAMMDD como acima, sem as barras o
resultado é nenhum registro.
Edit1.Text := ´02/02/2004´;
Edit2.Text := ´03/02/2004´;
Parameters.ParamByName(´DtIni´).Value := StrToDate(Edit1.Text);
Parameters.ParamByName(´DtFin´).Value := StrToDate(Edit2.Text);
- Se eu colocar com entrada normal de dados e convertendo string para
Data, o resultado continua sendo 03/02/2004, 02/03/2004 e
02/04/2004 e naos os registros do dia 02 e 03 do mês 02 de 2004.
if Opc = ´4´ then
begin
with ADOQuery do
begin
if Active then close;
SQL.Clear;
SQL.Add(´SELECT * FROM Mensagem WHERE Mensagem_DATA BETWEEN (:DtIni) and (:DtFin)´);
Parameters.ParamByName(´DtIni´).Value := StrToDate(Edit1.Text);
Parameters.ParamByName(´DtFin´).Value := StrToDate(Edit2.Text);
Open;
end;
end;
Da para vc. modificar o exemplo acima, mostrando como deve ser
O B R I G A D O.......
Gostei + 0
05/08/2004
Vinicius2k
Acho q vc continua sem entender o que eu disse...
Sua rotina está correta (se vc usar tipo Date no Banco), a instrução SQL também... o problema é no processamento da instrução no BANCO.
Vc precisa mudar a forma de ARMAZENAR a data no Banco de Dados.
Duas opções :
1 - armazena a data como string de 8 posições invertida sem barras, então vc usa a consulta como vc tentou fazendo a inversão...
2 - armazena a data como tipo date, então não precisa alterar nada na rotina...
De uma forma ou de outra vc vai ter que alterar a estrutura do seu Banco de Dados e provavelmente, dados já armazenados, se não vc nunca vai ter o resultado desejado na consulta.
T+
Gostei + 0
05/08/2004
Rogerio_amorim
É como o colega Vinicius2K informou, para retornar uma consulta entre datas corretamente como vc precisa, é simples, utilize campos tipo data.
OK
Rogerio Amorim
Gostei + 0
05/08/2004
Canastra
Alterei o campo para data, e funcionou muito bem. Porém não poderei mudar o campo para data, pois a base já funciona assim na Internet e o programador do mesmo não quer mudar, sendo que a
minha parte que se refere ao programa que utiliza a base para administração da empresa poderá ficar sem funcionar nesta parte devido este transtorno.
Se tiver alguma sugestão do DBGrid da query, apresentar a consulta de uma outra forma, nao sendo SQL ou de outra qualquer agradeço.
Abraço, e muito O B R I G A D O ...................
Gostei + 0
05/08/2004
Vinicius2k
Bem, esta é só uma idéia, que pode ou ser ser possível de implementar, mas...
Vc está usando ADOQueries/ADODatasets diretamente ou com Provider + ClientDataSet ? Se a Query estiver ligada diretamente ao DBGrid, mude a estrutura, acrescentando um DataSetProvider + ClientDataSet para intermediar o fetch dos registros :
ADOQuery -> DataSetProvider -> ClientDataSet -> DataSource ->DBGrid
Mude a instrução SQL da ADOQuery, retirando a cláusula where, ela traga todos os registros... vc fará, então, um filtro local...
No ClientDataSet vc pode criar um campo calculado do tipo Date e no OnCalcFields vc implentaria :
ClientDataSet1.FieldByName(´campo_calculado´).AsDate := StrToDate(ClientDataSet1.FieldByName(´campo_original´));
Ainda no ClientDataSet, mude a propriedade ´Filtered´ para True e no evento OnFilterRecord vc implentaria :
Accept:= (ClientDataSet1.FieldByName(´campo_calculado´).AsDate >= StrToDate(Edit1.Text) ) and (ClientDataSet1.FieldByName(´campo_calculado´).AsDate <= StrToDate(Edit2.Text));
Espero ter ajudado...
T+
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)