Firebird + IBX: проблемы с timestamp и TDateTimeField

IBX, FIBPlus, UIB, ADO, .Net и прочее-прочее-прочее, в общем все, что относится к созданию приложений, работающих с InterBase, Firebird и Yaffil - клиент-серверных, трехзвенных, консольных и т.п.

Модератор: kdv

gvy
Сообщения: 9
Зарегистрирован: 28 авг 2006, 14:13

Firebird + IBX: проблемы с timestamp и TDateTimeField

Сообщение gvy » 28 авг 2006, 15:16

Перевожу программу, успешно проработавшую 5 лет под разными версиями InterBase, на Firebird 2.0 RC4.
Возникла проблема c типом timestamp и соответствующим ему TDateTimeField в программе.

1.Генерируется update SQL, в который в WHERE добавляются условия для полей, которые
изменились. Что-то наподобие:

update table_name
set timestamp_field = current_timestamp
where timestamp_field = :old_timestamp_field and ...;

2. При изменении в программе поля типа timestamp (через TDateTimeField) в Firebird этот update
не обновляет запись, получаю ошибку "Update failed".

3. Причина - функция current_timestamp в InterBase не возвращает доли секунды (всегда нули),
а в Firebird - возвращает. Кто не верит, выполните для обеих баз:
select cast( current_timestamp as varchar(32) ) from rdb$database;

Дальше, если посмотреть в логе, какой параметр реально подставляется при выполнении вместо
:old_timestamp_field, то увидим, что это дата + время, без долей секунд, т.к. TDateTimeField их
и не должен содержать.

Вот и получается, если в базе timestamp уже с долями секунды, то условие
timestamp_field = :old_timestamp_field эту запись не выберет.

Что по этому поводу скажут специалисты?

P.S. Попытка вместо TDateTimeField использовать TSQLTimeStampField не увенчалась успехом,
т.к. IBX говорит, что ожидал SQLTimeStamp, а реально получил DateTime.

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 28 авг 2006, 15:24

IBX вообще не умеет работать со временем точнее секунды. Выбросить его нафиг.

gvy
Сообщения: 9
Зарегистрирован: 28 авг 2006, 14:13

Сообщение gvy » 28 авг 2006, 15:29

Я бы так и сделал, но нету ни времени, ни желания кардинально менять старую отлаженную программу, и за это никто не даст денег. Жду ответов по существу.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 28 авг 2006, 15:36

gvy писал(а):Я бы так и сделал, но нету ни времени, ни желания кардинально менять старую отлаженную программу, и за это никто не даст денег. Жду ответов по существу.
Тогда закатывай рукава, бери напильник и обработай им IBX. По этим долям секунды широкие массы дружно страдали много лет и наконец-то выпросили. Ты попал в категорию, которая "попала". Такая категория всегда бывает, к сожалению.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 28 авг 2006, 15:37

варианты

1. оставить программу на версии FB, в которой current_timestamp не возвращает миллисекунды
2. попробовать использовать cast('now' as timestamp)

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 28 авг 2006, 15:48

gvy писал(а):Жду ответов по существу.
Тогда у тебя есть небогатый выбор:
  • Доступаться к sqlvar напрямую (как это делаю я)
    Переписать работу AsDateTime
    Передавать строку.

gvy
Сообщения: 9
Зарегистрирован: 28 авг 2006, 14:13

Сообщение gvy » 28 авг 2006, 15:49

Ясно. Просто интересно, автор IBX вообще ещё поддерживает своё творение? Что-то с момента выхода IBX 6.08 прошло слишком много времени. И где ему пожаловаться, существует в природе официальный сайт IВX?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 28 авг 2006, 15:52

кстати, IBX тут на первый взгляд ни при чем. стандартные типы столбцов описаны в DB.PAS.
вполне может кончится тем, что current_timestamp вернут обратно, и сделают current_timestampms или что-то вроде.

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 28 авг 2006, 15:57

А на второй взгляд становится ясно, что миллисекунды отпадают при использовании isc_encode/decode_date() в методах Get/SetAsDateTime.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 28 авг 2006, 15:59

Что-то с момента выхода IBX 6.08 прошло слишком много времени.
изменения только вместе с новыми версиями дельфей. Политика вполне понятная.
официального сайта ibx не существует, т.к. ibx это часть софта Borland. То есть, официальный сайт IBX тут:
http://codecentral.borland.com/Author.aspx?ID=102

добавлю, что в IBX для D2006 в плане timestamp вроде бы все то же самое.

gvy
Сообщения: 9
Зарегистрирован: 28 авг 2006, 14:13

Сообщение gvy » 28 авг 2006, 16:06

Я как раз и делаю это в C++ Builder 2006.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 28 авг 2006, 16:12

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

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

Причем, на fb2 таким образом перестанут работать все приложения, которые работают в IBX (как минимум. Бузаджи сейчас FIBPlus проверяет на эту тему) и других драйверах, которые миллисекунды в timestamp не учитывают (по разным причинам).

так что я за возврат старой функциональности и введение нестандартного current_timestampmsec

dimitr
Разработчик Firebird
Сообщения: 888
Зарегистрирован: 26 окт 2004, 16:20

Сообщение dimitr » 28 авг 2006, 16:19

кому нужен timestamp без секунд - пусть юзает current_timestamp(0), возможность таковая есть. А если IBX до сих пор не умеет работать с миллисекундами во времени - это их проблемы, IB это поддерживает уже лет 15 как.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 28 авг 2006, 16:32

продолжаем. стандартные функции форматирования даты-времени в дельфях могут показать миллисекунды, если указать формат

hh:mm:ss.zzz

только вот 3 цифры под миллисекунды, и все. если написать zzzz - все равно 3 цифры выводится.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 28 авг 2006, 16:40

кстати, о птичках. существующие 15 лет в IB миллисекунды - не миллисекунды, а десятые миллисекунд. Потому что миллисекунды, это 0.nnn. Я не знаю, как дело с форматированием времени в других языках, поэтому прошу прокомментировать.

то есть, я не знаю, как стандартными средствами в Delphi ввести или вывести десятые миллисекунды. StrToDateTime работает в пределах стандартного формата миллисекунд - zzz.

p.s. что IBX миллисекунды обрезает - это уже другой вопрос.

gvy
Сообщения: 9
Зарегистрирован: 28 авг 2006, 14:13

Сообщение gvy » 28 авг 2006, 17:10

Да, current_timestamp(0) решает проблему. Но всё равно все старые приложения придётся переделывать. Не очень хорошо. Вот он, призрак обратной совместимости :-)

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 28 авг 2006, 17:14

Ну, положим, не все, а работавшие вопреки здравому смыслу, используя старинную багу...

gvy
Сообщения: 9
Зарегистрирован: 28 авг 2006, 14:13

Сообщение gvy » 28 авг 2006, 17:23

Ключевое слово тут было "работавшие" ;-) Ладно, посмотрим, что на это скажут разработчики сервера.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 28 авг 2006, 17:31

разработчик уже сказал. под FB2 переделывать на current_timestamp(0). или ты имел в виду разработчиков приложений?

to Merlin: я к тому, что миллисекунды это не 0.nnnn, а 0.nnn. То есть даже то что в IB было 15 лет, все равно "не соответствует".

buzz
Сообщения: 4
Зарегистрирован: 03 фев 2005, 23:46

Сообщение buzz » 28 авг 2006, 17:46

В общем FIBplus работает как положено и ничего не теряется. Вопрошавшему же посоветую повесить на эту несчастную таблицу триггер, который через
current_timestamp(0) просто занулит ненужные вам доли секунды.

Ответить