由 C 到 SQL 的 datetime 数类型转换
适用于:SQL Server
Azure SQL 数据库
Azure SQL 托管实例
Azure Synapse Analytics Analytics
平台系统(PDW)
本主题列出了从 C 类型转换为 SQL Server 日期/时间类型时要考虑的问题。
下表中介绍的转换适用于在客户端上所进行的转换。 如果客户端为与服务器上定义的参数指定小数秒精度,则客户端转换可能会成功,但在调用 SQLExecute 或 SQLExecuteDirect 时,服务器将返回错误。 具体而言,ODBC 将小数秒的任何截断视为错误,而 SQL Server 行为是舍入;例如,从 datetime2(6) 到 datetime2(2)时发生舍入。 Datetime 列值舍入为 1/300 秒,服务器将 smalldatetime 列的秒数设置为零。
SQL_TYPE_DATE | SQL_TYPE_TIME | SQL_SS_TIME2 | SQL_TYPE_TIMESTAMP | SQL_SS_TIMSTAMPOFFSET | SQL_CHAR | SQL_WCHAR | |
---|---|---|---|---|---|---|---|
SQL_C_DATE | 1 | - | - | 1,6 | 1,5,6 | 1,13 | 1,13 |
SQL_C_TIME | - | 1 | 1 | 1,7 | 1,5,7 | 1,13 | 1,13 |
SQL_C_SS_TIME2 | - | 1,3 | 1,10 | 1,7 | 1,5,7 | 1,13 | 1,13 |
SQL_C_BINARY(SQL_SS_TIME2_STRUCT) | 空值 | 空值 | 1,10,11 | 空值 | 不可用 | 不可用 | 空值 |
SQL_C_TYPE_TIMESTAMP | 1,2 | 1,3,4 | 1,4,10 | 1,10 | 1,5,10 | 1,13 | 1,13 |
SQL_C_SS_TIMESTAMPOFFSET | 1,2,8 | 1,3,4,8 | 1,4,8,10 | 1,8,10 | 1,10 | 1,13 | 1,13 |
SQL_C_BINARY(SQL_SS_TIMESTAMPOFFSET_STRUCT) | 空值 | 不可用 | 不可用 | 空值 | 1,10,11 | 空值 | 空值 |
SQL_C_CHAR/SQL_WCHAR(日期) | 9 | 9 | 9 | 9,6 | 9,5,6 | 空值 | 空值 |
SQL_C_CHAR/SQL_WCHAR (time2) | 9 | 9,3 | 9,10 | 9,7,10 | 9,5,7,10 | 空值 | 空值 |
SQL_C_CHAR/SQL_WCHAR (datetime) | 9,2 | 9,3,4 | 9,4,10 | 9,10 | 9,5,10 | 空值 | 空值 |
SQL_C_CHAR/SQL_WCHAR (datetimeoffset) | 9,2,8 | 9,3,4,8 | 9,4,8,10 | 9,8,10 | 9,10 | 空值 | 空值 |
SQL_C_BINARY(SQL_DATE_STRUCT) | 1,11 | 空值 | 不可用 | 不可用 | 不可用 | 不可用 | 空值 |
SQL_C_BINARY(SQL_TIME_STRUCT) | 空值 | 不可用 | 不可用 | 不可用 | 不可用 | 不可用 | 空值 |
SQL_C_BINARY(SQL_TIMESTAMP_STRUCT) | 空值 | 不可用 | 不可用 | 不可用 | 不可用 | 不可用 | 空值 |
符号含义
-:不支持转换。 生成具有 SQLSTATE 07006 和消息“受限制的数据类型属性冲突”的诊断记录。
1:如果提供的数据无效,则使用 SQLSTATE 22007 和消息“日期/时间格式无效”生成诊断记录。
2:时间字段必须为零,或者使用 SQLSTATE 22008 和消息“小数截断”生成诊断记录。
3:小数秒必须为零,或者使用 SQLSTATE 22008 和消息“小数截断”生成诊断记录。
4:忽略日期组件。
5:时区设置为客户端的时区设置。
6:时间设置为零。
7:日期设置为当前日期。
8:时间从客户端时区转换为 UTC。 如果在此转换过程中发生错误,则生成具有 SQLSTATE 22008 和消息“日期时间字段溢出”的诊断记录。
9:根据遇到的第一个标点符号字符以及剩余组件的存在,将字符串分析并转换为日期、日期/时间、日期/时间值。 然后,根据上表中针对此过程发现的源类型的规则,此字符串将转换为目标类型。 如果在分析数据时检测到错误,则生成具有 SQLSTATE 22018 和消息“为转换指定的字符值无效”的诊断记录。 对于 datetime 和 smalldatetime 参数,如果年份超出这些类型支持的范围,则生成具有 SQLSTATE 22007 和消息“日期时间格式无效”的诊断记录。
对于 datetimeoffset,在转换为 UTC 后该值必须处于规定范围内,即使不要求转换为 UTC。 这是因为 TDS 和服务器始终规范化 UTC 的 datetimeoffset 值中的时间,因此在转换为 UTC 后,客户端必须确认时间部分处于支持的范围内。 如果值不在支持的 UTC 范围内,则生成具有 SQLSTATE 22007 和消息“日期时间格式无效”的诊断记录。
10:如果发生数据丢失截断,则会使用 SQLSTATE 22008 和消息“时间格式无效”生成诊断记录。 如果值处于服务器使用的 UTC 范围可表示的范围外,也会发生此错误。
11:如果数据的字节长度不等于 SQL 类型所需的结构的大小,则会使用 SQLSTATE 22003 生成诊断记录,并生成消息“数值超过范围”。
12:如果数据的字节长度为 4 或 8,则数据以原始 TDS smalldatetime 或 datetime 格式发送到服务器。 如果数据的字节长度与 SQL_TIMESTAMP_STRUCT 大小完全匹配,则将该数据转换为 datetime2 的 TDS 格式。
13:如果发生数据丢失截断,则会使用 SQLSTATE 22001 和消息“字符串数据,右截断”生成诊断记录。
小数秒位数(小数位数)根据下表从目标列的大小确定:
暗指的小数位数 暗指的小数位数 类型 0 1..9 SQL_C_TYPE_TIMESTAMP 19 21..29 但是,对于 SQL_C_TYPE_TIMESTAMP,如果秒的小数部分可以在不丢失数据的情况下由三位数表示,并且列大小为 23 或更大,则生成确切的三位数的秒小数部分。 此行为确保使用早期 ODBC 驱动程序开发的应用程序的向后兼容性。
对于大于表中范围的列大小,则暗指小数位数为 9。 此转换应允许的秒的小数部分位数多达 9 位,这是 ODBC 允许的最大位数。
列大小为零则暗指 ODBC 中可变长度字符类型的大小无限制(即 9 位,除非应用 SQL_C_TYPE_TIMESTAMP 的三位数规则)。 指定列大小为零且具有固定长度的字符类型是错误的。
N/A:维护现有的 SQL Server 2005(9.x)和更早的行为。
另请参阅
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈