I have an C++ dll that connects to a SQL Server 2008 database and executes a stored procedure. SQL Server is using compatibility level 80 for this database. The connection to the server is done through ADO using the SQL Server OLE_DB driver. The customer wants to upgrade to SQL Server 2012, which only supports compatibility level 90 and above.
The stored procedure takes two varchar input values and returns 2 varchar and 2 integer output values. The C++ code in the DLL creates and initializes 7 VARIANTs, then adds 7 parameters to ADO connection object’s parameters collection using those variants. The VARIANT and parameters types are as follows:
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
After executing the command, the values from the output VARIANTS are retrieved and returned to the calling program.
The value being returned by the stored procedure in the ret_barcode parameter is a value read from the data base. When this dll is tested against SQL Server 2012, the varchar values are not being returned properly. The actual value contained in the ret_barcode VARIANT is the text “return_more_rows”, which is the name of the last output parameter! If at the very end of the stored procedure I set the value of the ret_barcode parameter to a string constant, the proper value will show up in the C++ dll, as long as the string constant is 13 characters or less.
A simple C# test program using ADO.NET behaved as expected.
If I change the type of the ret_barcode variable in the stored procedure to a char(30), the proper value is returned in the ret_barcode VARIANT. While debugging I used the Parameter.Refresh method to determine what type of parameters the stored procedure was expecting. In both cases, the ret_barcode parameter was adVarChar. This leads me to believe that there is a difference in how the server is packing and transmitting the data to the client depending on its compatibility level.
What I read about compatibility levels seem to indicate that they simple expose or restrict features. Does anybody know what changed between compatibility level 80 and 90 to cause this problem or what I can do in the DLL to support varchar data from the DB?