Улучшения поддержки типов данных даты и времени OLE DB

Применимо к: SQL Server Azure SQL DatabaseУправляемый экземпляр SQL AzureAzure Synapse Analytics AnalyticsPlatform System (PDW)

Скачать драйвер OLE DB

В этой статье предоставляются сведения о типах OLE DB (OLE DB Driver for SQL Server), которые поддерживают типы данных даты или времени SQL Server.

Сопоставление типов данных в наборах строк и параметрах

Для поддержки серверов новых типов OLE DB предоставляет два новых типа данных: DBTYPE_DBTIME2 и DBTYPE_DBTIMESTAMPOFFSET. Следующая таблица отображает полное сопоставление типов серверов.

Тип данных SQL Server Тип данных OLE DB Значение
DATETIME DBTYPE_DBTIMESTAMP 135 (oledb.h)
smalldatetime DBTYPE_DBTIMESTAMP 135 (oledb.h)
Дата DBTYPE_DBDATE 133 (oledb.h)
time DBTYPE_DBTIME2 145 (msoledbsql.h)
datetimeoffset DBTYPE_DBTIMESTAMPOFFSET 146 (msoledbsql.h)
datetime2 DBTYPE_DBTIMESTAMP 135 (oledb.h)

Форматы данных: строки и литералы

Тип данных SQL Server Тип данных OLE DB Формат строки для клиентских преобразований
DATETIME DBTYPE_DBTIMESTAMP 'гггг-мм-дд чч:мм:сс:[.999]'

SQL Server для типа Datetime поддерживает значения долей секунды, состоящие из не более чем трех цифр.
smalldatetime DBTYPE_DBTIMESTAMP 'гггг-мм-дд чч:мм:сс'

Точность этого типа данных составляет одну минуту. При выводе данных секунды будут равны нулю, а при вводе данных они округляются сервером.
Дата DBTYPE_DBDATE 'гггг-мм-дд'
time DBTYPE_DBTIME2 'чч:мм:сс[.9999999]'

Дополнительно можно указывать доли секунд до семи цифр.
datetime2 DBTYPE_DBTIMESTAMP 'гггг-мм-дд чч:мм:сс[.еееееее]'

Дополнительно можно указывать доли секунд до семи цифр.
datetimeoffset DBTYPE_DBTIMESTAMPOFFSET 'гггг-мм-дд чч:мм:сс[.еееееее] +/-чч:мм'

Дополнительно можно указывать доли секунд до семи цифр.

В escape-последовательностях для литералов даты и времени изменений нет.

Для долей секунды в результатах используется точка (.), а не двоеточие (:).

Строковые значения, возвращаемые в приложения, всегда будут иметь одинаковую длину для данного столбца. Компоненты года, месяца, дня, часа, минуты и секунды дополняются ведущими нулями до максимальной длины. Между значениями даты и времени имеется точно один пробел, а также предусмотрен точно один пробел между значением времени и смещением часового пояса. Перед смещением часового пояса всегда должен стоять знак. Это знак «плюс» (+), если смещение равен нулю. Пробелы между знаком и значением смещения отсутствуют. Доли секунды дополняются замыкающими нулями при необходимости до заданной точности столбца, но не более. Для столбцов datetime количество цифр с обозначением долей секунды равно трем. Для столбцов smalldatetime цифры с обозначением долей секунды отсутствуют, а секунды всегда равны нулю.

Приложения позволяют применять более гибкие преобразования из строковых значений, а также обеспечивают возможность использования значений компонентов с меньшей шириной по сравнению с максимальной. Годы могут быть представлены цифрами в количестве от 1 до 4. Месяцы, дни, часы, минуты и секунды могут быть представлены 1 или 2 цифрами. Между значениями даты и времени, а также значением времени и смещением часового пояса может находиться произвольное число пробелов. Смещение, равное нулю часов и нулю минут, может иметь знак плюс или минус. Допускается использование замыкающих нулей для долей секунд вплоть до максимального количества цифр, равного 9. Время может завершаться десятичной запятой без указания цифр долей секунды.

Пустая строка не является допустимым литералом даты-времени, она не представляет значение NULL. Попытка преобразовать пустую строку в значение даты-времени приведет к ошибкам со значением SQLState, равным 22018, и сообщением «Недопустимое символьное значение для спецификации приведения».

Форматы данных: структуры данных

В структурах, зависящих от поставщика OLE DB, на OLE DB налагаются указанные ниже ограничения. Следующие определения взяты из описания григорианского календаря.

  • Диапазон месяцев — от 1 до 12 включительно.

  • Диапазон поля даты — от 1 до количества дней в месяце включительно, он должен быть согласован с полями года и месяца с учетом високосного года.

  • Диапазон часов — от 0 до 23 включительно.

  • Диапазон минут — от 0 до 59 включительно.

  • Диапазон секунд — от 0 до 59. Это позволяет использовать до двух корректировочных секунд для синхронизации со звездным временем.

Реализации следующих существующих структур OLE DB были изменены в целях совместимости с новыми типами данных даты и времени SQL Server. При этом определения не изменились.

  • DBTYPE_DATE (это тип даты для автоматизации. Внутри системы он имеет формат double, где целая часть обозначает количество дней, начиная с 30 декабря 1899 года, а дробная — долю дня. Этот тип имеет точность в 1 секунду, а следовательно эффективную шкалу 0.)

  • DBTYPE_DBDATE

  • DBTYPE_DBTIME

  • DBTYPE_DBTIMESTAMP (Поле дробной части определяется в OLE DB как число миллиардных долей секунды (наносекунд) и имеет диапазон от 0 до 999 999 999.)

  • DBTYPE_FILETIME

DBTYPE_DBTIME2

Эта структура дополняется до 12 байт как в 32-разрядных, так и в 64-разрядных операционных системах.

typedef struct tagDBTIME2 {  
    USHORT hour;  
    USHORT minute;  
    USHORT second;  
    ULONG fraction;  
    } DBTIME2;  

DBTYPE_ DBTIMESTAMPOFFSET

typedef struct tagDBTIMESTAMPOFFSET {  
    SHORT year;  
    USHORT month;  
    USHORT day;  
    USHORT hour;  
    USHORT minute;  
    USHORT second;  
    ULONG fraction;  
    SHORT timezone_hour;  
    SHORT timezone_minute;  
    } DBTIMESTAMPOFFSET;  

Если значение timezone_hour отрицательно, значение timezone_minute должно быть отрицательным или нулевым. Если значение timezone_hour положительно, значение timezone minute должно быть положительным или нулевым. Если значение timezone_hour равно нулю, timezone minute может содержать значение от -59 до +59.

SSVARIANT

Эта структура изменена и теперь содержит новые типы DBTYPE_DBTIME2 и DBTYPE_DBTIMESTAMPOFFSET, а также шкалу дробных долей секунды для соответствующих типов.

struct SSVARIANT {  
   SSVARTYPE vt;  
   DWORD dwReserved1;  
   DWORD dwReserved2;  
   union {  
// ...  
      DBTIMESTAMP tsDateTimeVal;  
      DBDATE dDateVal;  
      struct _Time2Val {  
         DBTIME2 tTime2Val;  
         BYTE bScale;  
      } Time2Val;  
      struct _DateTimeVal {  
         DBTIMESTAMP tsDateTimeVal;  
         BYTE bScale;  
      } DateTimeVal;  
      struct _DateTimeOffsetVal {   
         DBTIMESTAMPOFFSET tsoDateTimeOffsetVal;  
         BYTE bScale;  
      } DateTimeOffsetVal;  
// ...  
   };  
};  

Кроме того, перечисление, связанное с типом шифрования SSVARIANT, который определяет тип перечисления, будет расширено следующим образом:

enum SQLVARENUM {  
// ...  
   // Datetime  
   VT_SS_DATETIME      = DBTYPE_DBTIMESTAMP,  
   VT_SS_SMALLDATETIME = 206,  
  
   VT_SS_DATE = DBTYPE_DBDATE,  
   VT_SS_TIME2 = DBTYPE_DBTIME2,  
   VT_SS_DATETIME2 = 212  
   VT_SS_DATETIMEOFFSET = DBTYPE_DBTIMESTAMPOFFSET  
};  

Переводимые на использование OLE DB Driver for SQL Server приложения, которые используют тип данных sql_variant и полагаются на ограниченную точность datetime, следует обновить, если базовая схема обновлена для использования типа данных datetime2 вместо datetime.

Макрос доступа SSVARIANT также расширен с помощью следующего дополнения:

#define V_SS_DATETIME2(X)       V_SS_UNION(X, DateTimeVal)  
#define V_SS_TIME2(X)           V_SS_UNION(X, Time2Val)  
#define V_SS_DATE(X)            V_SS_UNION(X, dDateVal)  
#define V_SS_DATETIMEOFFSET(X)  V_SS_UNION(X, DateTimeOffsetVal)  

Сопоставление типов данных в методе ITableDefinition::CreateTable

Следующее сопоставление типов используется со структурами DBCOLUMNDESC в ITableDefinition::CreateTable:

тип данных OLE DB (wType) Тип данных SQL Server Примечания
DBTYPE_DBDATE Дата
DBTYPE_DBTIMESTAMP datetime2(p) OLE DB Driver for SQL Server проверяет элемент DBCOLUMDESC bScale, пытаясь определить точность долей секунды.
DBTYPE_DBTIME2 time(p) OLE DB Driver for SQL Server проверяет элемент DBCOLUMDESC bScale, пытаясь определить точность долей секунды.
DBTYPE_DBTIMESTAMPOFFSET datetimeoffset(p) OLE DB Driver for SQL Server проверяет элемент DBCOLUMDESC bScale, пытаясь определить точность долей секунды.

Если приложение задает DBTYPE_DBTIMESTAMP в wType, оно может заменить сопоставление на datetime2, предоставив имя типа в pwszTypeName. Если указано datetime, bScale должен быть равен 3. Если указано smalldatetime, bScale должен быть равен 0. Если bScale не согласуется с wType и pwszTypeName, возвращается DB_E_BADSCALE.

См. также:

Улучшения функций даты и времени (OLE DB)