OdbcParameter错误 - varchar(MAX)输出参数

时间:2017-11-13 14:04:18

标签: c# sql-server stored-procedures odbc

我正在使用:

  

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

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

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

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

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

  

System.InvalidOperationException未处理
  的HResult = -2146233079
  Message = String [2]:Size属性的无效大小为0   来源= System.Data
  堆栈跟踪:
         at System.Data.Odbc.OdbcParameter.GetParameterSize(Object value,Int32 offset,Int32 ordinal)
         在System.Data.Odbc.OdbcParameter.PrepareForBind(OdbcCommand命令,Int16 ordinal,Int32&amp; parameterBufferSize)
         在System.Data.Odbc.OdbcParameterCollection.CalcParameterBufferSize(OdbcCommand)   命令)
         在System.Data.Odbc.OdbcCommand.ExecuteReaderObject(CommandBehavior   behavior,String方法,Boolean needReader,Object [] methodArguments,   SQL_API odbcApiMethod)
         在System.Data.Odbc.OdbcCommand.ExecuteReaderObject(CommandBehavior   行为,String方法,Boolean needReader)
         在System.Data.Odbc.OdbcCommand.ExecuteNonQuery()

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

  

System.Data.Odbc.OdbcException未处理
  错误码= -2146232009
  的HResult = -2146232009
  Message = ERROR [42000] [Microsoft] [ODBC SQLServer驱动程序] [SQL Server]无效参数2(&#39;&#39;):数据类型0x23是   不推荐使用的大对象或LOB,但标记为输出参数。   不支持不推荐使用的类型作为输出参数。使用当前   而是大型对象类型。 Source = SQLSRV32.DLL StackTrace:
         在System.Data.Odbc.OdbcConnection.HandleError(OdbcHandle hrHandle,RetCode retcode)
         在System.Data.Odbc.OdbcCommand.ExecuteReaderObject(CommandBehavior   behavior,String方法,Boolean needReader,Object [] methodArguments,   SQL_API odbcApiMethod)
         在System.Data.Odbc.OdbcCommand.ExecuteReaderObject(CommandBehavior   行为,String方法,Boolean needReader)
         在System.Data.Odbc.OdbcCommand.ExecuteNonQuery()

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

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

编辑:如果实际答案是&#34;你就是不能&#34;#34;然后这是可以接受的 - 至少我肯定会知道。

2 个答案:

答案 0 :(得分:2)

如果您想坚持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

答案 1 :(得分:1)

SQL Server 2005中引入了

varchar(max)来替换text类型。当值小于8000时,它会像标准varchar(n)一样存储在页面上,而超过8000的值会像text一样存储在页面之外。

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

  

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

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

此外,您可以使用不同的(较旧的)ODBC驱动程序版本来解决这个问题,该驱动程序并不抱怨使用varchar(max)作为输出参数,但这显然不是最好的要走的路。