Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
ABC+mssql2008R2
В базе MS SQL поле даты определено как DATE и импортируется в dct как STRING(3). И вот тут я напрягся! Не получается записать в sql-поле дату - получаю ошибки преобразования и т.п. Видимо, надо как-то хитро объявить это sql-поле в dct или ещё что-то?
Как решить эту проблему?
P.S. если в sql поле объявлено как datetime, то с этим всё уже давно понятно, а если date - то
Мда. Оговорюсь сразу, мне ещё не приходилось работать с форматом MS SQL Date в Кларионе.
Проверил по help'у от MS SQL. Действительно занимает 3 байта. Начало отсчёта берёт от 1900-01-01.
В Кларионе DATE определяется как 4-байтное поле, начинающееся с 1801-01-01.
Поэтому логичным было бы написать две функции преобразования MSSQL Date --> Clarion Date, и, наоборот, Clarion Date --> MSSQL Date.
При работе в Кларионе при получении данных конвертировать в одну сторону и пользоваться стандартными контролами и стандартными функциями, а перед сохранением конвертировать в обратную сторону.
Clarion 7.1 and higher provides support for the new data types introduced in SQL Server 2008.
Here are the new data types and their Clarion representations:
SQL Server 2008 Data Type Clarion Conversion
DATE DATE
Плюс. Посмотрел у нас, мы подключаемся к 1С-овской базе. У нас в словаре поля обозначены как Date, всё работает, нет проблем.
Связь с 1С - не моя тема, в понедельник спрошу у спецов. Но в С6.3, по-моему, в словаре тоже тип Date.
А через скульный Insert дату мы закидываем посредством format(FIL:Date,@d10-). Работает на всех SQL.
1. В доке указано, что для драйвера MS SQL поле Datetime отображается либо в кларионовскую Date, либо в структуру из полей Date и Time по вкусу
2. Если мы считываем поле средствами ODBC, тогда лучше прочитать дату в поле String, а потом разобрать оное через Deformat(Loc:DateString,@d10-)
3. Если мы пишем средствами ODBC, то рекомендуется преобразовать дату в строку по формату @d12, а строку передать серверу Dummy{Prop:SQL} = 'Insert into table(datefield) values('' ' & format(Loc:Clariondate,@d12) & '') '
Посмотрел в словаре С6.3 - идёт как Date. А в доке по MS SQL - 3 байта от "0001-01-01" до "9999-12-31". Поэтому пересчитывать поле Long, наверно, неправильно, можно нарваться. Кстати, я так понимаю, что все SQL дату считают от "0001-01-01". Почему в Кларионе по-другому?
kreator писал(а): все SQL дату считают от "0001-01-01"
Почему все-то? Даже в MS SQL это не совсем так.
У MSSQL Date (subj) отсчитываются от 1900-01-01 (диапазон 0001-01-01 - 9999-12-01).
У MSSQL Datetime соответственно -- 1900-01-01 (1753-01-01 - 9999-12-01).
У MSSQL smalldatetime -- 1900-01-01 (1900-01-01 - 2079-06-06)
Shur писал(а):У MSSQL Date (subj) отсчитываются от 1900-01-01 (диапазон 0001-01-01 - 9999-12-01).
А что такое диапазон? Нижняя граница диапазона и есть откуда считается дата. Или не так?
Для того и привёл здесь разные форматы. Даже если вы считаете началом отсчета нижнюю границу диапазона, то нельзя не заметить, что в трёх приведённых форматах они разные.
Так откуда же тогда утверждение, что:
kreator писал(а): я так понимаю, что все SQL дату считают от "0001-01-01"
Shur писал(а):Даже если вы считаете началом отсчета нижнюю границу диапазона, то нельзя не заметить, что в трёх приведённых форматах они разные.
У MS SQL много специфических типов данных. Но если брать ходовые Time, Date и DateTime2, то вот так. Firebird не обладает расширенными типами, но тоже пляшет от 1 января 1 года. Sybase тоже самое. Oracle и MySQL специфичны. А по поводу 1753 года есть целая гипотеза - якобы осталось от Sybase, а этот год - год принятия в Великобритании григорианского календаря (кто-то в Sybase был повёрнут на этой теме).
declare @d1 date = '0001-01-01'
select @d1,convert(binary(3),@d1) -- возвращает '0x000000'
declare @d2 date = '1900-01-01'
select @d2,convert(binary(3),@d2) -- возвращает '0x5B950A', что соответствует числу 0A955B, или 693595
declare @d3 date = '1801-01-01'
select @d3,convert(binary(3),@d3) -- возвращает '0x1C080A', что соответствует числу 0A081C, или 657436