我使用的是:
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
输出参数,并将其添加到OdbcCommand
Parameters
列表中:
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¶meterBufferSize)
在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
一样存储在页外。
不建议使用text
或varcha(max)
作为参数,正如消息所告诉您的,输出参数甚至不支持它:
数据类型0x23是一个不推荐使用的大型对象或LOB,但被标记为输出参数。不支持不推荐的类型作为输出参数。请改用当前的大型对象类型。
最好的解决方案是修复存储过程并将输出参数从varchar(max)
更改为varchar(n)
。否则,您可以在代码中使用varchar(8000)
作为参数,并希望存储过程永远不会返回超过8000的值。值8000是varchar(n)
类型的最大值。
此外,您可以使用不同(旧)版本的ODBC驱动程序来绕过它,该驱动程序不会抱怨使用varchar(max)
作为输出参数,但这显然不是最好的方法。