У меня есть C ++ dll, который подключается к базе данных SQL Server 2008 и выполняет хранимую процедуру. SQL Server использует уровень совместимости 80 для этой базы данных. Подключение к серверу осуществляется через ADO с использованием драйвера OLE_DB для SQL Server. Клиент хочет перейти на SQL Server 2012, который поддерживает только уровень совместимости 90 и выше.
Хранимая процедура принимает два входных значения varchar и возвращает 2 выходных значения varchar и 2 целых числа. Код C ++ в DLL создает и инициализирует 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, является значением, считанным из базы данных. Когда эта DLL проверена на SQL Server 2012, значения varchar не возвращаются должным образом. Фактическим значением, содержащимся в ret_barcode VARIANT, является текст «return_more_rows”, Который является названием последнего выходного параметра! Если в самом конце хранимой процедуры я установлю значение параметра ret_barcode в строковую константу, правильное значение будет отображаться в DLL C ++, если строковая константа составляет 13 символов или менее.
Простая тестовая программа на C # с использованием ADO.NET вела себя так, как и ожидалось.
Если я изменю тип переменной ret_barcode в хранимой процедуре на char (30), верное значение возвращается в VARIANT ret_barcode. Во время отладки я использовал метод Parameter.Refresh, чтобы определить, какой тип параметров ожидает хранимая процедура. В обоих случаях параметром ret_barcode был adVarChar. Это наводит меня на мысль, что существует разница в том, как сервер упаковывает и передает данные клиенту в зависимости от его уровня совместимости.
То, что я читал об уровнях совместимости, указывает на то, что они просто раскрывают или ограничивают возможности. Кто-нибудь знает, что изменилось между уровнем совместимости 80 и 90, чтобы вызвать эту проблему, или что я могу сделать в DLL для поддержки данных varchar из БД?
Задача ещё не решена.
Других решений пока нет …