我正在使用:
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;然后这是可以接受的 - 至少我肯定会知道。
答案 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)
varchar(max)
来替换text
类型。当值小于8000时,它会像标准varchar(n)
一样存储在页面上,而超过8000的值会像text
一样存储在页面之外。
不推荐使用text
或varcha(max)
作为参数,正如消息告诉您的那样,输出参数甚至不支持它:
数据类型0x23是不推荐使用的大对象或LOB,但标记为输出参数。不支持不推荐使用的类型作为输出参数。改为使用当前的大对象类型。
最佳解决方案是修复存储过程并将输出参数从varchar(max)
更改为varchar(n)
。否则,您可以在代码中使用varchar(8000)
作为参数,并希望存储过程永远不会返回超过8000的值。值8000是varchar(n)
类型的最大值。
此外,您可以使用不同的(较旧的)ODBC驱动程序版本来解决这个问题,该驱动程序并不抱怨使用varchar(max)
作为输出参数,但这显然不是最好的要走的路。