Неправильный результат после нажатия кнопки Обновить в DBNavigator Delphi

StackOverflow https://stackoverflow.com/questions/1865842

Вопрос

Я столкнулся здесь с очень странной ситуацией.Я получаю доступ к базе данных (MDB) через JET.Я использую DBGrid и DBNavigator, чтобы разрешить пользователю доступ к нему.Набор данных создается с помощью компонента TADOQuery со следующим запросом:

SELECT *, (DateDiff ('y',[Birth Date], Now())) AS [Age] FROM TableName

Это работает нормально.Но всякий раз, когда я нажимаю кнопку Обновления в DBNavigator, результат этого вычисляемого поля становится неправильным.Например, если обычно у меня в столбце Возраст отображается 7, то после нажатия кнопки Обновить оно становится 40149, 7 изменяется на 40149, 6 изменяется на 40150, 0 на 40156 и т.д.Чтобы просмотреть правильный результат, мне нужно снова повторно открыть запрос.

Кто-нибудь может помочь?

Это было полезно?

Решение

Попробуйте следующее, которое вернет возраст в днях.

SELECT *, CINT(Now()-[Birth Date]) as AGE FROM TableName

Для возраста в годах используйте:

SELECT *, INT((Now()-[Birth Date]) / 365.242199) as AGEYRS from TableName

(обратите внимание, CINT округляет, INT - нет)

Причина, по которой это работает, заключается в том, что ACCESS сохраняет свою дату / время методом, аналогичным Delphi, в виде значения с плавающей точкой, где целая часть представляет собой количество дней, прошедших с определенного дня, а дробная часть - дробную часть этого дня ( 0.25 = 6 утра, 0.50 = полдень и т.д.).Таким образом, если вы хотите узнать разницу между двумя днями, просто возьмите разницу между номерами дней...что касается количества лет, разделите это на количество дней в году.

Редактировать

Другим вариантом здесь было бы создать вычисляемое поле в Delphi и выполнить логику там.В вашем onCalculated событии вы бы закодировали что-то вроде следующего:

procedure TForm1.ds1CalcFields(DataSet: TDataSet);
begin
  DataSet.FieldByName('CALCDATE').AsInteger := 
    Trunc((Date - DataSet.FieldByName('BIRTH DATE').AsDateTime) / 365.242199);
end;

Редактировать

И еще третий способ.Вместо того, чтобы разрешать обновлению работать так, как оно работает в данный момент, переопределите поведение и принудительно закройте / повторно откройте набор данных с помощью onClick навигатора:

procedure TForm1.dbnvgr1Click(Sender: TObject; Button: TNavigateBtn);
begin
  if Button = nbRefresh then
    begin
      ds1.Close;
      ds1.Open;
    end;
end;

Другие советы

Попробуйте вместо этого использовать этот параметр интервала :

SELECT *, (DateDiff ('yyyy',[Birth Date], Now())) AS [Age] FROM TableName

Вот что означает "интервалы" :

yyyy    Year
q   Quarter
m   Month
y   Day of Year
d   Day
w   Weekday
ww  Week
h   Hour
n   Minute
s   Second

Я провел тест с вашим предыдущим комментарием, и у меня тоже такая же ошибка.

Я думаю, это ошибка где-то в навигаторе или в jet.

Когда вы нажмете обновить навигатор.показанный 40149 - это представление даты в виде двойного значения без вычисляемого материала.Похоже, что он использует только первый найденный столбец и отображает его.

Если вы попытаетесь преобразовать его в строку, отображаемые данные по-прежнему будут datetime.

Select *, ' ' & DateDiff(.......) as [Age] From table1;

Когда я использую столбец типа String или Number первым в вычисляемом поле, результат отображается так, как должен.Вы можете попробовать :

SELECT *,  mid(id & (DateDiff ('y',[madate], Now())), len(id) + 1) AS [Age] FROM Table1

Или :

SELECT *,  (id-id) + (DateDiff ('y',[madate], Now()))  AS [Age] FROM Table1

Это довольно некрасиво, но это делает свое дело..

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top