我有一个连接到 SQL Server 2008 数据库并执行存储过程的 C++ dll。SQL Server 正在为此数据库使用兼容级别 80。与服务器的连接是通过 ADO 使用 SQL Server OLE_DB 驱动程序完成的。客户想升级到SQL Server 2012,只支持兼容级别90及以上。
存储过程接受两个 varchar 输入值并返回 2 个 varchar 和 2 个整数输出值。DLL 中的 C++ 代码创建并初始化 7 个 VARIANT,然后使用这些变量将 7 个参数添加到 ADO 连接对象的参数集合中。VARIANT 和参数类型如下:
0 VT_I4 “RETURN_VALUE” adInteger adParamReturnValue
1 VT_BSTR “barcode” adVarChar adParamInput
2 VT_BSTR “inParam2” adVarChar adParamInput
3 VT_BSTR “ret_barcode” adVarChar adParamOutput
4 VT_I4 “ret_param2” adInteger adParamOutput
5 VT_I4 “ret_param3” adInteger adParamOutput
6 VT_BSTR “return_more_rows” adVarChar adParamOutput
执行命令后,将检索输出 VARIANTS 中的值并将其返回给调用程序。
ret_barcode 参数中的存储过程返回的值是从数据库中读取的值。针对 SQL Server 2012 测试此 dll 时,未正确返回 varchar 值。ret_barcode VARIANT 中包含的实际值是文本“<strong>return_more_rows”,它是最后一个输出参数的名称!如果在存储过程的最后我将 ret_barcode 参数的值设置为字符串常量,只要字符串常量不超过 13 个字符,正确的值就会显示在 C++ dll 中。
使用 ADO.NET 的简单 C# 测试程序按预期运行。
如果我将存储过程中的 ret_barcode 变量的类型更改为 char(30),则在 ret_barcode VARIANT 中返回正确的值。在调试时,我使用 Parameter.Refresh 方法来确定存储过程所期望的参数类型。在这两种情况下,ret_barcode 参数都是 adVarChar。这使我相信服务器打包数据并将数据传输到客户端的方式会有所不同,具体取决于其兼容性级别。
我读到的有关兼容性级别的内容似乎表明它们只是公开或限制功能。有谁知道兼容性级别 80 和 90 之间发生了什么变化导致了这个问题,或者我可以在 DLL 中做什么来支持来自 DB 的 varchar 数据?