【问题标题】:Using sql-server datetime2 with TADOQuery.open使用带有 TADOQuery.open 的 sql-server datetime2
【发布时间】:2016-07-29 15:27:35
【问题描述】:

我想开始在 SQL Server 中使用datetime2 字段,我需要通过 Delphi XE5 中的 ADO 插入表中。我正在使用TADOQuery.ExecSQL 插入,一切正常。

但是我的大多数表都有标识列,例如

id integer identity(1,1) not null

为了节省到服务器的往返次数,我通常在查询文本中使用Open 和两个命令。

  • 第一个命令是插入
  • 第二条命令是“select scope_identity() as scope_id”

所以我可以在同一次往返中检索新插入的 id

这对我的所有表格都有效,但现在当我添加 datetime2time 列时 - 我收到错误:

项目“Foo.exe 引发异常类 EOleException 并显示消息“从字符串转换日期和/或时间时转换失败”。

如果这很重要,我正在使用 SQL Server 2008。有谁知道可能是什么问题?

【问题讨论】:

    标签: sql-server delphi ado delphi-xe


    【解决方案1】:

    问题是datetime2 没有返回到使用 SQLOLEDB 提供程序作为正确 ADO 数据类型 (adDBTimestamp) 的 ADO 客户端:

    adDBTimeStamp (135)

    表示日期/时间戳(yyyymmddhhmmss 加上十亿分之一)(DBTYPE_DBTIMESTAMP)。

    相反,它以 unicode 字符串 (adVarWChar) 的形式返回:

    adVarWChar (202)

    表示一个以 null 结尾的 Unicode 字符串。

    • 2016-11-03 12:06:01.0000000

    SQL Server 本地客户端 (SQLNCLI)

    可以尝试切换到 “本机” OLEDB 提供程序之一(例如 SQLNCLI、SQLNCLI10、SQLNCLI11)。问题在于:

    • 操作系统不附带 SQL Server Native 客户端(您必须在客户端 PC 上自行安装)
    • the SQL Server Native Client is derpricated
    • SQLNCLI 提供程序将 XML 列公开为不受支持的 ADO DataTypeEnum 值(141,DBTYPE_XML)
    • SQLNCLI 提供程序将 TIME 列公开为不受支持的 ADO DataTypeEnum 值 (145)
    • SQLNCLI 提供程序将 UDT 列公开为不受支持的 ADO DataTypeEnum 值 (132)

    您可以在连接字符串中使用DataTypeCompatibility=80 选项来使XML 列返回为adLongVarWChar(就像它们在SQLOLEDB 中所做的那样),然后datetime2datetime 作为字符串返回

    使用DataTypeCompatibility=80 的问题是本机客户端驱动程序中存在错误。它错误地将 SQL Server DATE 列从 adDBDate 转换为 adVarWChar

     | SQL Server data type | SQLOLEDB        | SQLNCLI            | SQLNCLI w/DataTypeCompatibilyt=80 |
     |----------------------|-----------------|--------------------|-----------------------------------|
     | Xml                  | adLongVarWChar  | 141 (DBTYPE_XML)   | adLongVarChar                     |
     | datetime             | adDBTimeStamp   | adDBTimeStamp      | adDBTimeStamp                     |
     | datetime2            | adVarWChar      | adDBTimeStamp      | adVarWChar                        |
     | date                 | adVarWChar      | adDBDate           | adVarWChar                        |
     | time                 | adVarWChar      | 145 (unknown)      | adVarWChar                        |
     | UDT                  |                 | 132 (DBTYPE_UDT)   | adVarBinary (documented,untested) |
     | varchar(max)         | adLongVarChar   | adLongVarChar      | adLongVarChar                     |
     | nvarchar(max)        | adLongVarWChar  | adLongVarWChar     | adLongVarWChar                    |
     | varbinary(max)       | adLongVarBinary | adLongVarBinary    | adLongVarBinary                   |
     | timestamp            | adBinary        | adBinary           | adBinary                          |
    

    SQL Native Client Provider was documented on MS Connect 中的这个错误。但是微软的人不明白他被告知了什么,将其关闭为不会修复

    因此,如果您真的想使用 ADO 中的 datetime2,则必须将其读取为 字符串,并自行解析。

    阅读奖励

    【讨论】:

    • 你是对的。但是我在哪里发现字符串包含日期时间?请注意,您正在从一个您一无所知的表中查询。
    • @AminAlinezhad 您希望查询返回列的 type,以便您知道它实际上是一个日期 - 并照此处理。只要您使用 ADOdb,就不会发生这种情况。您必须直接使用 OLEDB API,而这是您不想想要了解的内容。这是一个极其复杂的 OLEDB API(这就是创建 ADO 和 ADO.net 的原因——作为 OLEDB 的包装器)。您只需要知道“是”一个日期时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-22
    相关资源
    最近更新 更多