ODBC 日期/时间数据类型支持改进

本主题提供有关支持 SQL Server 日期和时间数据类型的 ODBC 类型的信息。

参数和结果集中的数据类型映射

除了 ODBC 数据类型(SQL_TYPE_TIMESTAMP 和 SQL_TIMESTAMP)以外,在 SQL Server Native Client ODBC 中还需要两种新数据类型以公开新的服务器类型:

  • SQL_SS_TIME2

  • SQL_TIMESTAMPOFFSET

下表显示完整的服务器类型映射。注意,该表的某些单元格包含两个条目;在这些情况下,第一个是针对 ODBC 3.0 的值,第二个是针对 ODBC 2.0 的值。

SQL Server 数据类型

SQL 数据类型

Datetime

SQL_TYPE_TIMESTAMP

SQL_TIMESTAMP

93 (sql.h)

11 (sqlext.h)

Smalldatetime

SQL_TYPE_TIMESTAMP

SQL_TIMESTAMP

93 (sql.h)

11 (sqlext.h)

Date

SQL_TYPE_DATE

SQL_DATE

91 (sql.h)

9 (sqlext.h)

Time

SQL_SS_TIME2

-154 (SQLNCLI.h)

DatetimeOFFSET

SQL_SS_TIMESTAMPOFFSET

-155 (SQLNCLI.h)

Datetime2

SQL_TYPE_TIMESTAMP

SQL_TIMESTAMP

93 (sql.h)

11 (sqlext.h)

下表列出了相应的结构和 ODBC C 类型。由于 ODBC 不允许驱动程序定义的 C 类型,因此将 SQL_C_BINARY 作为二进制结构用于 time 和 datetimeoffset。

SQL 数据类型

内存布局

默认 C 数据类型

值 (sqlext.h)

SQL_TYPE_TIMESTAMP

SQL_TIMESTAMP

SQL_TIMESTAMP_STRUCT

TIMESTAMP_STRUCT

SQL_C_TYPE_TIMESTAMP

SQL_C_TIMESTAMP

SQL_TYPE_TIMESTAMP

SQL_TIMESTAMP

SQL_TYPE_DATE

SQL_DATE

SQL_DATE_STRUCT

DATE_STRUCT

SQL_C_TYPE_DATE

SQL_C_DATE

SQL_TYPE_DATE

SQL_DATE

SQL_SS_TIME2

SQL_SS_TIME2_STRUCT

SQL_C_BINARY

SQL_BINARY (-2)

SQL_SS_TIMESTAMPOFFSET

SQL_SS_TIMESTAMPOFFSET_STRUCT

SQL_C_BINARY

SQL_BINARY (-2)

指定 SQL_C_BINARY 绑定时,将执行对齐检查,并对不正确的对齐报错。该错误的 SQLSTATE 将是 IM016,并显示消息“结构对齐不正确”。

数据格式:字符串和文字

下表显示 SQL Server 数据类型、ODBC 数据类型和 ODBC 字符串文字之间的映射。

SQL Server 数据类型

ODBC 数据类型

客户端转换的字符串格式

Datetime

SQL_TYPE_TIMESTAMP

SQL_TIMESTAMP

'yyyy-mm-dd hh:mm:ss[.999]'

SQL Server 支持 Datetime 秒的小数部分最多为三位数。

Smalldatetime

SQL_TYPE_TIMESTAMP

SQL_TIMESTAMP

'yyyy-mm-dd hh:hh:ss'

该数据类型的精度可精确到一分钟。秒部分在输出时将是零,在输入时由服务器舍入。

Date

SQL_TYPE_DATE

SQL_DATE

'yyyy-mm-dd'

Time

SQL_SS_TIME2

'hh:mm:ss[.9999999]'

可以选择使用最多七位数指定秒的小数部分。

Datetime2

SQL_TYPE_TIMESTAMP

SQL_TIMESTAMP

'yyyy-mm-dd hh:mm:ss[.9999999]'

可以选择使用最多七位数指定秒的小数部分。

DatetimeOFFSET

SQL_SS_TIMESTAMPOFFSET

'yyyy-mm-dd hh:mm:ss[.9999999] +/- hh:mm'

可以选择使用最多七位数指定秒的小数部分。

日期/时间文字的 ODBC 转义序列没有更改。

结果中秒的小数部分始终使用点 (.),而不是冒号 (:)。

返回到应用程序的字符串值始终与给定列的长度相同。年、月、日、小时、分钟和秒部分将以前置零填充至其最大宽度,并且 datetime 值中的日期和时间之间有一个空格。在 datetimeoffset 值的时间和时区偏移量之间也有一个空格。时区偏移量前面始终有一个符号;如果偏移量是零,则该符号是加号 (+)。如有必要,秒的小数部分将填充尾随零,直到达到列的定义精度。对于 datetime 列,秒的小数部分有三位数。对于 smalldatetime 列,秒部分没有小数位,并且秒将始终是零。

空字符串不是有效的日期/时间文字,并且它不表示 NULL 值。将空字符串转换到日期/时间值的尝试将导致 SQLState 22018 错误并显示消息“为转换指定的字符值无效。”。

从字符串参数进行转换应当得到相同格式的字符串,不过,包含零小时和零分钟的时区的符号可以是加号或减号,并且允许秒的小数部分的尾随零最多可达 9 位数。时间部分可以以小数点终止,并且秒没有小数位。

当前,驱动程序允许标点字符前后有额外的空白,并且时间和时区偏移量之间的空格是可选的。但是,这可能在未来版本中更改;应用程序不应当依赖于当前行为。

数据格式:数据结构

在下面描述的结构中,ODBC 指定了来自公历的以下约束:

  • 月的范围是 1 到 12。

  • 日字段的范围是 1 到月份中的天数,并且必须与年和月字段一致且考虑到闰年。

  • 小时范围是 0 到 23。

  • 分钟范围是 0 到 59。

  • 秒范围是 0 到 61.9(n)。这允许最多两个闰秒以便与恒星时间保持同步。

    注意,SQL Server 不允许闰秒,因此大于 59 的秒值将导致服务器错误。

以下现有 ODBC 结构的实现已修改,以支持新的 SQL Server 日期和时间数据类型。但是,尚未更改定义。

  • DATE_STRUCT

  • TIME_STRUCT

  • TIMESTAMP_STRUCT

还有两个新结构:

  • SQL_SS_TIME2_STRUCT

  • SQL_SS_TIMESTAMPOFFSET_STRUCT

SQL_SS_TIME2_STRUCT

该结构是 SQL Server 2008 中的新结构,而且在 32 位和 64 位操作系统上都填充到 12 字节。

typedef struct tagSS_TIME2_STRUCT {
   SQLUSMALLINT hour;
   SQLUSMALLINT minute;
   SQLUSMALLINT second;
   SQLUINTEGER fraction;
} SQL_SS_TIME2_STRUCT;

SQL_SS_TIMESTAMPOFFSET_STRUCT

该结构是 SQL Server 2008 中的新结构:

typedef struct tagSS_TIMESTAMPOFFSET_STRUCT {
   SQLSMALLINT year;
   SQLUSMALLINT month;
   SQLUSMALLINT day;
   SQLUSMALLINT hour;
   SQLUSMALLINT minute;
   SQLUSMALLINT second;
   SQLUINTEGER fraction;
   SQLSMALLINT timezone_hour;
   SQLSMALLINT timezone_minute;
} SQL_SS_TIMESTAMPOFFSET_STRUCT;

如果 timezone_hour 是负数,则 timezone_minute 必须是负数或零。如果 timezone_hour 是正数,则 timezone_minute 必须是正数或零。如果 timezone_hour 是零,则 timezone_minute 可能是 -59 到 +59 范围内的任何值。