Risultato errato dopo Refresh premuto sulla DBNavigator Delphi
-
18-09-2019 - |
Domanda
ho affrontato una situazione molto strana qui. Io sono l'accesso di database (MDB) attraverso JET. Io uso DBGrid e DBNavigator per consentire l'accesso degli utenti esso. Set di dati viene creato utilizzando componenti TADOQuery, con la seguente query:
SELECT *, (DateDiff ('y',[Birth Date], Now())) AS [Age] FROM TableName
Funziona bene. Ma ogni volta che si preme il pulsante Aggiorna sulla DBNavigator il risultato di questo campo calcolato diventa sbagliato. Ad esempio, se, di solito ho mostrato a 7 colonna Age, se si preme di aggiornamento diventa 40149, 7 modifiche a 40149, 6 modifiche a 40150, 0 a 40156 etc. Per visualizzare il risultato corretto ho bisogno di riaprire di nuovo query.
Chiunque può aiutare?
Soluzione
Prova il seguente, che restituirà l'età in giorni.
SELECT *, CINT(Now()-[Birth Date]) as AGE FROM TableName
Per l'età in anni d'uso:
SELECT *, INT((Now()-[Birth Date]) / 365.242199) as AGEYRS from TableName
(si noti, CINT arrotonda, INT non fa)
La ragione per cui questo funziona è che Access memorizza la data / ora in un metodo simile a Delphi, come un galleggiante dove la parte intera è il numero di giorni da un determinato giorno e la parte frazionaria come la parte frazionaria di quel giorno (0,25 = 06:00, 0,50 = mezzogiorno, ecc). Quindi se volete sapere le differenze tra due giorni, basta prendere le differenze tra i numeri al giorno ... per numero di anni, dividere questo per il numero di giorni in un anno.
Modifica
Un'altra opzione sarebbe di creare un campo calcolato in Delphi ed eseguire la logica là. Nel vostro evento onCalculated si codice simile al seguente:
procedure TForm1.ds1CalcFields(DataSet: TDataSet);
begin
DataSet.FieldByName('CALCDATE').AsInteger :=
Trunc((Date - DataSet.FieldByName('BIRTH DATE').AsDateTime) / 365.242199);
end;
Modifica
E tuttavia un terzo metodo. Piuttosto che permettere il refresh di lavorare come fa attualmente, ignorare il comportamento e forzare la chiusura / riapertura del set di dati utilizzando l'onClick del navigatore:
procedure TForm1.dbnvgr1Click(Sender: TObject; Button: TNavigateBtn);
begin
if Button = nbRefresh then
begin
ds1.Close;
ds1.Open;
end;
end;
Altri suggerimenti
Prova questo parametro intervallo invece:
SELECT *, (DateDiff ('yyyy',[Birth Date], Now())) AS [Age] FROM TableName
Ecco cosa significa "intervalli" significa:
yyyy Year
q Quarter
m Month
y Day of Year
d Day
w Weekday
ww Week
h Hour
n Minute
s Second
Ho fatto una prova con il commento precedente, e ho anche lo stesso errore.
Credo che sia un errore da qualche parte nel navigatore o in jet.
Quando si ha colpito aggiornare sul NAV. il 40149 indicato è la rappresentazione data come un doppio, senza la roba calcolato. E sembra usare solo la prima colonna trovato e per visualizzarla.
Se si tenta di lanciare in una stringa, dati visualizzati è ancora un datetime.
Select *, ' ' & DateDiff(.......) as [Age] From table1;
Quando uso una colonna di tipo stringa o numero prima nel campo calcolato, il risultato viene visualizzato come dovrebbe. Si può provare:
SELECT *, mid(id & (DateDiff ('y',[madate], Now())), len(id) + 1) AS [Age] FROM Table1
o
SELECT *, (id-id) + (DateDiff ('y',[madate], Now())) AS [Age] FROM Table1
Questo è abbastanza brutto, ma fa il trucco ..