Resultado errado depois de actualização pressionado sobre DBNavigator Delphi
-
18-09-2019 - |
Pergunta
Eu enfrentei uma situação muito estranha aqui. Eu estou acessando banco de dados (MDB) através JET. Eu uso DBGrid e DBNavigator para permitir o acesso de usuário dele. Conjunto de dados é criado usando o componente TADOQuery, com a seguinte consulta:
SELECT *, (DateDiff ('y',[Birth Date], Now())) AS [Age] FROM TableName
Ele funciona muito bem. Mas sempre que eu pressione o botão Atualizar na DBNavigator o resultado deste campo calculado se torna errado. Por exemplo, se normalmente tenho 7 mostrado na coluna Age, depois de premir Atualizar torna-se 40149, 7 muda para 40.149, 6 modificações a 40150, 40156 a 0, etc. Para visualizar resultado correto eu preciso reabrir consulta novamente.
Qualquer pessoa pode ajudar?
Solução
Tente o seguinte, que voltará a idade em dias.
SELECT *, CINT(Now()-[Birth Date]) as AGE FROM TableName
Para a idade em anos usar:
SELECT *, INT((Now()-[Birth Date]) / 365.242199) as AGEYRS from TableName
(note, rodadas CINT, INT não)
A razão que isso funciona é que lojas de acessar seus data / hora em um método semelhante como Delphi, como uma bóia, onde a parte inteira é o número de dias desde que um dia específico e a parte fracionária como a parte fracionária do dia (0,25 = 06:00, 0,50 = meio-dia, etc). Assim, se você quer saber as diferenças entre dois dias, basta levar as diferenças entre os números de dias ... para o número de anos, divide isso pelo número de dias em um ano.
Editar
Outra opção aqui seria criar um campo calculado em Delphi e executar a lógica lá. Em seu evento onCalculated faria código algo como o seguinte:
procedure TForm1.ds1CalcFields(DataSet: TDataSet);
begin
DataSet.FieldByName('CALCDATE').AsInteger :=
Trunc((Date - DataSet.FieldByName('BIRTH DATE').AsDateTime) / 365.242199);
end;
Editar
E ainda um terceiro método. Ao invés de permitir que a atualização para o trabalho como faz atualmente, substituir o comportamento e forçar um close / reabrir do conjunto de dados usando a onClick do navegador:
procedure TForm1.dbnvgr1Click(Sender: TObject; Button: TNavigateBtn);
begin
if Button = nbRefresh then
begin
ds1.Close;
ds1.Open;
end;
end;
Outras dicas
Tente este parâmetro intervalo em vez disso:
SELECT *, (DateDiff ('yyyy',[Birth Date], Now())) AS [Age] FROM TableName
Aqui está o que "intervalos" significa:
yyyy Year
q Quarter
m Month
y Day of Year
d Day
w Weekday
ww Week
h Hour
n Minute
s Second
Eu fiz um teste com o seu comentário anterior, e eu também tenho o mesmo erro.
Eu acho que é um lugar bug no Navigator ou no jet.
Quando você bate atualização no nav. a 40149 mostrado é a representação data como um duplo sem o material calculado. Ele parece usar apenas a primeira coluna encontrado e para exibi-lo.
Se você tentar lançá-lo para uma cadeia, os dados exibidos ainda é uma data e hora.
Select *, ' ' & DateDiff(.......) as [Age] From table1;
Quando eu uso uma coluna do tipo String ou Número pela primeira vez no campo calculado, o resultado é exibido como deveria. Você pode tentar:
SELECT *, mid(id & (DateDiff ('y',[madate], Now())), len(id) + 1) AS [Age] FROM Table1
Ou:
SELECT *, (id-id) + (DateDiff ('y',[madate], Now())) AS [Age] FROM Table1
Isso é muito feio, mas ele faz o truque ..