我有一个SQL CLR函数,它从Web Api返回Json,这里是我的代码
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlString Funcion()
{
SqlString document;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("URL");
request.Method = "GET";
request.ContentLength = 0;
request.Credentials = CredentialCache.DefaultCredentials;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream);
document = (SqlString)readStream.ReadToEnd();
return document;
}
我删除下一个代码,因为我认为这是问题
//response.Close();
//readStream.Close();
但我仍然犯了错误
System.ObjectDisposedException: Cannot read from a closed TextReader System.ObjectDisposedException:
at System.IO.__Error.ReaderClosed()
at System.IO.StreamReader.ReadToEnd()
at UserDefinedFunctions.Funcion()
我用ILSpy检查dll,我的代码看起来不一样 有人可以帮忙。我在应用程序cosole中尝试了这个代码,将结果写入文件并完美地运行
答案 0 :(得分:2)
很难准确地说出您将当前代码与已注释/删除的代码分开。但是将location
用于字符串以返回字符串的一般概念是正确的方法。
如果您不希望此代码丢弃您的SQL Server,您绝对需要做的一件事是正确处理所有一次性对象。您应该使用ReadToEnd
构造,因为它们将包含正确的using()
结构,以确保所有资源都得到正确处理,无论它们在嵌套集中的哪个位置发生异常。
现在,从ILspy中获取的图像中显示的代码显示了它正在返回try...finally
的直接问题。将代码放入正确的readStream.ReadToEnd()
构造中,并在中间执行using
后,这将按预期工作。
document = (SqlString)readStream.ReadToEnd()
<强>更新强>
string document;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("URL");
request.Method = "GET";
request.ContentLength = 0;
request.UseDefaultCredentials = true; // don't use CredentialCache.DefaultCredentials;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream receiveStream = response.GetResponseStream())
{
using (StreamReader readStream = new StreamReader(receiveStream))
{
document = readStream.ReadToEnd();
}
}
}
return new SqlString(document);
错误。问题是不返回数据类型的映射,因为将其映射到Cannot read from a closed TextReader
而不是NVARCHAR(4000)
会导致以下错误:
Ms 6522,Level 16,State 1,Line 2
在执行用户定义的例程或聚合“xxxxxx”期间发生.NET Framework错误:
System.Data.SqlServer.TruncationException:尝试将大小为24233896字节的返回值或输出参数转换为大小限制为8000字节的T-SQL类型。
System.Data.SqlServer.TruncationException:
在System.Data.SqlServer.Internal.CXVariantBase.StringToWSTR(String pstrValue,Int64 cbMaxLength,Int32 iOffset,EPadding ePad)