Страница 1 из 2
ClarionDate => ms sql date
Добавлено: 24 Январь 2016, 10:42
morkovin
ABC+mssql2008R2
В базе MS SQL поле даты определено как DATE и импортируется в dct как STRING(3). И вот тут я напрягся! Не получается записать в sql-поле дату - получаю ошибки преобразования и т.п. Видимо, надо как-то хитро объявить это sql-поле в dct или ещё что-то?
Как решить эту проблему?
P.S. если в sql поле объявлено как datetime, то с этим всё уже давно понятно, а если date - то

ClarionDate => ms sql date
Добавлено: 24 Январь 2016, 13:17
Shur
Мда. Оговорюсь сразу, мне ещё не приходилось работать с форматом MS SQL Date в Кларионе.
Проверил по help'у от MS SQL. Действительно занимает 3 байта. Начало отсчёта берёт от 1900-01-01.
В Кларионе DATE определяется как 4-байтное поле, начинающееся с 1801-01-01.
Поэтому логичным было бы написать две функции преобразования MSSQL Date --> Clarion Date, и, наоборот, Clarion Date --> MSSQL Date.
При работе в Кларионе при получении данных конвертировать в одну сторону и пользоваться стандартными контролами и стандартными функциями, а перед сохранением конвертировать в обратную сторону.
ClarionDate => ms sql date
Добавлено: 24 Январь 2016, 14:10
kreator
Есть подозрение, что импорт неправильно работает. Кстати, какой Кларион? По хелпу десятки:
Код: Выделить всё
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, всё работает, нет проблем.
ClarionDate => ms sql date
Добавлено: 24 Январь 2016, 15:42
morkovin
Кстати, какой Кларион?
C6.2(9049)
А в с10 импортирует нормально(но в действии не проверял.)

- 24.01.png (8.88 КБ) 5067 просмотров
Поэтому логичным было бы написать две функции преобразования MSSQL Date --> Clarion Date, и, наоборот, Clarion Date --> MSSQL Date
Обычно хватает : MSSQL Date=ClarionDate - 36163
Пришлось использовать DUMMY(PROP:Sql)='INSERT INTO...'
А читать обратно мне не нужно.
ClarionDate => ms sql date
Добавлено: 24 Январь 2016, 17:26
kreator
Связь с 1С - не моя тема, в понедельник спрошу у спецов. Но в С6.3, по-моему, в словаре тоже тип Date.
А через скульный Insert дату мы закидываем посредством format(FIL:Date,@d10-). Работает на всех SQL.
ClarionDate => ms sql date
Добавлено: 24 Январь 2016, 17:44
Yufil
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) & '') '
Впрочем, наверное это не о том...
ClarionDate => ms sql date
Добавлено: 24 Январь 2016, 20:31
Shur
morkovin писал(а): Обычно хватает : MSSQL Date=ClarionDate - 36163
Вроде должно быть 36159 (365*(1900-1801)+24)
ClarionDate => ms sql date
Добавлено: 24 Январь 2016, 20:38
Дед Пахом
Дата 01.01.1801 в Кларионе имеет значение 4.
ClarionDate => ms sql date
Добавлено: 24 Январь 2016, 21:13
Shur
Shur писал(а): morkovin писал(а): Обычно хватает : MSSQL Date=ClarionDate - 36163
Вроде должно быть 36159 (365*(1900-1801)+24)
Дед Пахом писал(а): Дата 01.01.1801 в Кларионе имеет значение 4.
Ух, чёрт, верно!
ClarionDate => ms sql date
Добавлено: 25 Январь 2016, 11:14
kreator
Посмотрел в словаре С6.3 - идёт как Date. А в доке по MS SQL - 3 байта от "0001-01-01" до "9999-12-31". Поэтому пересчитывать поле Long, наверно, неправильно, можно нарваться. Кстати, я так понимаю, что все SQL дату считают от "0001-01-01". Почему в Кларионе по-другому?
ClarionDate => ms sql date
Добавлено: 25 Январь 2016, 11:59
Shur
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)
ClarionDate => ms sql date
Добавлено: 25 Январь 2016, 14:11
kreator
Shur писал(а):У MSSQL Date (subj) отсчитываются от 1900-01-01 (диапазон 0001-01-01 - 9999-12-01).
А что такое диапазон? Нижняя граница диапазона и есть откуда считается дата. Или не так?
ClarionDate => ms sql date
Добавлено: 25 Январь 2016, 14:26
Shur
kreator писал(а): Shur писал(а):У MSSQL Date (subj) отсчитываются от 1900-01-01 (диапазон 0001-01-01 - 9999-12-01).
А что такое диапазон? Нижняя граница диапазона и есть откуда считается дата. Или не так?
Для того и привёл здесь разные форматы. Даже если вы считаете началом отсчета нижнюю границу диапазона, то нельзя не заметить, что в трёх приведённых форматах они разные.
Так откуда же тогда утверждение, что:
kreator писал(а): я так понимаю, что все SQL дату считают от "0001-01-01"
ClarionDate => ms sql date
Добавлено: 25 Январь 2016, 14:58
kreator
Shur писал(а):Даже если вы считаете началом отсчета нижнюю границу диапазона, то нельзя не заметить, что в трёх приведённых форматах они разные.
У MS SQL много специфических типов данных. Но если брать ходовые Time, Date и DateTime2, то вот так. Firebird не обладает расширенными типами, но тоже пляшет от 1 января 1 года. Sybase тоже самое. Oracle и MySQL специфичны. А по поводу 1753 года есть целая гипотеза - якобы осталось от Sybase, а этот год - год принятия в Великобритании григорианского календаря (кто-то в Sybase был повёрнут на этой теме).
ClarionDate => ms sql date
Добавлено: 25 Январь 2016, 15:02
Shur
Впрочем, началом отсчёта для формата MSSQL Date следует считать действительно 0001-01-01.
Ибо
Код: Выделить всё
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