OdbcParameter错误-varchar(MAX)输出参数的大小为0



我使用的是:

Microsoft SQL Server 2012(SP1)-11.0.3128.0(X64)2012年12月28日20:23:12
版权所有(c)Microsoft Corporation Enterprise Edition(64位)on Windows NT 6.2(Build 9200:)(Hypervisor)

我有一个存储过程,它有一个varchar(MAX)输出参数。

我通过OdbcCommand调用它,并创建了一个VarChar输出参数,并将其添加到OdbcCommandParameters列表中:

new OdbcParameter("@MaxField", OdbcType.VarChar)
{ Direction = ParameterDirection.Output, Size = -1 })

在调试时,我可以看到参数上的Size字段仍然是-1,但当我使用OdbcCommand.ExecuteNonQuery()运行查询时,我得到以下异常:

System.InvalidOperationException未处理
HResult=-2146233079
Message=String[2]:Size属性的大小无效。
Source=System.Data
StackTrace:
System.Data.Odbc.OdbcParameter.GetParameterSize(对象值,Int32偏移量,Int32序号)(OdbcCommand命令,Int16序数,Int32&parameterBufferSize)
在System.Data.Odbc.OdbcParameterCollection.CalcParameterBufferSize(OdbcCommand命令)
在System.Data.Odbc.OdbcCommand.ExecuterReaderObject(CommandBehaviorbehavior,String方法,Boolean needReader,Object[]methodArguments,SQL_API odbcApiMethod)
位于System.Data.Odbc.OdbcCommand.ExecuteReaderObject(CommandBehaviorbehavior,String方法,Boolean needReader)
在System.Data.Odbc.OdbcCommand.ExecuteNonQuery()

我尝试使用OdbcCommandBuilder.DeriveParameters(odbcCommand);检查从存储过程派生的参数信息,它说参数的大小为21474833647,但是,如果我尝试使用该值,我会得到一个不同的异常,告诉我

System.Data.Odbc.OdbcException未处理
ErrorCode=-2146232009
HResult=-214623209
Message=ERROR[42000][Microsoft][Odbc SQLServer驱动程序][SQL Server]无效参数2("):数据类型0x23为不推荐使用的大型对象或LOB,但被标记为输出参数。不支持不推荐的类型作为输出参数。使用当前改为大型对象类型。源=System.Data.Odbc.OdbcConnection.HHandleError(OdbcHandle-hrHandle,RetCode RetCode)处的SQLSRV32.DLL堆栈跟踪:
System.Data.Odbc.OdbcCommand.ExecuteReaderObject(CommandBehaviorbehavior,String方法,Boolean needReader,Object[]methodArguments,SQL_API odbcApiMethod)
位于System.Data.Odbc.OdbcCommand.ExecuteReaderObject(CommandBehaviorbehavior,String方法,Boolean needReader)
在System.Data.Odbc.OdbcCommand.ExecuteNonQuery()

我应该如何配置我的OdbcCommand输出参数以从存储过程接收此输出?

这是在现有的生产数据库中进行的,因此尝试更改字段的数据类型是最后的手段。正在选择的字段为varchar(max)

编辑:如果实际的答案是"你就是不能",那么这是可以接受的——至少我可以肯定。

如果您想坚持使用System.Data.Odbc,那么以下解决方法可能就足够了。对于存储过程

CREATE PROCEDURE [dbo].[HodorSpeaks] 
@repeat int = 1, 
@response varchar(max) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @whatHeSaid varchar(max);
SET @whatHeSaid = 'HODOR! ';
SELECT @response = REPLICATE(@whatHeSaid, @repeat);
END

C#代码

using (var cmd = new OdbcCommand())
{
cmd.Connection = conn;
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = 
"SET NOCOUNT ON; " +
"DECLARE @out varchar(max); " +
"EXEC dbo.HodorSpeaks @repeat=?, @response=@out OUTPUT; " +
"SELECT @out;";
cmd.Parameters.Add("?", OdbcType.Int).Value = 10000;
string resp = cmd.ExecuteScalar().ToString();
Console.WriteLine("{0} characters were returned", resp.Length);
}

告诉我

70000 characters were returned

varchar(max)是在SQLServer2005中引入的,用于取代text类型。当值小于8000时,它像标准varchar(n)一样存储在页面上,而大于8000的值像text一样存储在页外。

不建议使用textvarcha(max)作为参数,正如消息所告诉您的,输出参数甚至不支持它:

数据类型0x23是一个不推荐使用的大型对象或LOB,但被标记为输出参数。不支持不推荐的类型作为输出参数。请改用当前的大型对象类型。

最好的解决方案是修复存储过程并将输出参数从varchar(max)更改为varchar(n)。否则,您可以在代码中使用varchar(8000)作为参数,并希望存储过程永远不会返回超过8000的值。值8000是varchar(n)类型的最大值。

此外,您可以使用不同(旧)版本的ODBC驱动程序来绕过它,该驱动程序不会抱怨使用varchar(max)作为输出参数,但这显然不是最好的方法。

最新更新