Fórum Consulta entre Datas SQL com ADO - Nao Funciona????? #245550

04/08/2004

0

Estou usando Delphi 6/7 ADO, sendo o campo da tabela em ACCESS é string de 10 posiçoes. No form eu tenho 2 edits strings q recebe a Data Inicial e Final.

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

Canastra

Responder

Posts

04/08/2004

Vinicius2k

Colega,

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+


Responder

Gostei + 0

04/08/2004

Canastra

-No form estou apenas 2 componentes: Adoquery e Datasource
-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..........


Responder

Gostei + 0

04/08/2004

Vinicius2k

Colega,

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 :
02/02/2004 02/03/2004 02/04/2004 03/02/2004


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+


Responder

Gostei + 0

04/08/2004

Canastra

Edit1.Text := ´20040202´;
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.......


Responder

Gostei + 0

05/08/2004

Vinicius2k

Colega,

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+


Responder

Gostei + 0

05/08/2004

Rogerio_amorim

Caro Canastra,


É como o colega Vinicius2K informou, para retornar uma consulta entre datas corretamente como vc precisa, é simples, utilize campos tipo data.

OK



Rogerio Amorim


Responder

Gostei + 0

05/08/2004

Canastra

Vinicius,

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


Responder

Gostei + 0

05/08/2004

Vinicius2k

Caramba... vc quase ficou de mãos atadas por causa disso...

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+


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar