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 范围内的任何值。