切换到使用SQL Native Client(SQLNCLI)作为ADO的提供程序时,我们遇到了遗留应用程序的问题。
我们的原始连接字符串是:
Provider=SQLOLEDB; Server=host; Database=bob; Integrated Security=SSPI;
我们将其更改为:
Provider=SQLNCLI11; Server=host; Database=bob; Integrated Security=SSPI; DataTypeCompatibility=80;
我们发现,当使用adDBTimeStamp参数调用存储过程时,Native Client似乎将时间戳视为smalldatetime而不是datetime。这导致我们出现问题,因为我们将9月31日作为高端"高端"在一些比较中的日期,并且Native Client失败并且"无效的日期格式" SQLOLEDB没有问题的错误。
现在看起来我们可能只能在创建参数时从adDBTimeStamp更改为adDate作为数据类型,但是我想知道在我们继续并使代码更改之前是否在连接字符串中缺少某些内容
下面重现的VBScript代码。为避免疑问,日期格式为英国(年/月/日)之前有人建议我们应该使用12/31/9999 :-)但也要确认,CDate不会失败。
Set db = CreateObject("ADODB.Command")
' If Provider=SQLOLEDB then there is no error.
db.ActiveConnection = "Provider=SQLNCLI11; Server=host; Database=bob; Integrated Security=SSPI; DataTypeCompatibility=80;"
db.CommandText = "usp_FetchData"
db.CommandType = &H0004
' 135 is adDBTimeStamp
db.Parameters.Append db.CreateParameter("@screenDate", 135, 1, 20, CDate("31/12/9999"))
Set rs = CreateOBject("ADODB.RecordSet")
' Then this line fails with "Invalid date format" from SQLNCLI
rs.Open db
WScript.Echo rs.RecordCount
将日期时间回到2078(在smalldatetime的日期范围内)使错误消失。
如上所述,如果可以找到非代码更改修补程序,那就是我们所希望的,在我们开始之前必须将adDBTimeStamp更改为adDate。我预计DataTypeCompatiblity = 80表现为SQLOLEDB;不幸的是,当找到SQLNCLI使用的确切类型映射时,我的Google-fu失败了。
答案 0 :(得分:0)
最终可能找到了一个解决方案:通过MSDN页面Data Type Support for OLE DB Date and Time Improvements,最后有一个片段:
ITableDefinition中的数据类型映射:: CreateTable
以下类型映射与所使用的DBCOLUMNDESC结构一起使用 by ITableDefinition :: CreateTable:
[...转换表...]
当应用程序在wType中指定DBTYPE_DBTIMESTAMP时,它可以 通过提供类型名称覆盖到datetime2的映射 pwszTypeName。 如果指定了datetime,则bScale必须为3. If 指定smalldatetime,bScale必须为0. 如果不是bScale 与wType和pwszTypeName一致,返回DB_E_BADSCALE。
在测试中,似乎需要设置比例适用于SELECT和命令以及CreateTable的参数。因此,如果我们将上面的脚本更改为:
def authenticationSuccessHandler
...然后错误消失并执行存储过程。我们正处于测试的早期阶段,但如果这会导致问题,那么欢迎来自其他人的反馈。