- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
因此,我很快就学习了C#的方法(继承了此问题的完整菜鸟);我已经编写了以下代码,该代码调用了一个Web服务,该服务返回的JSON格式总是不正确的。这里的任务是获取JSON字符串并将其分成数组段,这些数组段将插入到SQL表中以进行进一步的分析和测试。即如果返回字符串是这样的
{1234:{5678:{1:{"key":"val","key":"val"},{2:{"key":"val","key":"val"}}}}
{1234}
{5678}
{1:{"key":"val","key":"val"}
{2:{"key":"val","key":"val"}
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction(DataAccess =
DataAccessKind.Read)]
public static SqlString TestParse(SqlString uri, SqlString username, SqlString passwd, SqlString postdata)
{
//-----
// The SqlPipe is how we send data back to the caller
SqlPipe pipe = SqlContext.Pipe;
SqlString document;
try
{
// Set up the request, including authentication
WebRequest req = WebRequest.Create(Convert.ToString(uri));
if (Convert.ToString(username) != null & Convert.ToString(username) != "")
{
req.Credentials = new NetworkCredential(
Convert.ToString(username),
Convert.ToString(passwd));
}
((HttpWebRequest)req).UserAgent = "CLR web client on SQL Server";
// Fire off the request and retrieve the response.
using (WebResponse resp = req.GetResponse())
{
using (Stream dataStream = resp.GetResponseStream())
{
//SqlContext.Pipe.Send("...get the data");
using (StreamReader rdr = new StreamReader(dataStream))
{
document = (SqlString)rdr.ReadToEnd();
rdr.Close();
//-----
string connectionString = null;
string sql = null;
connectionString = "Data source= 192.168.0.5; Database=Administration;User Id=Foo;Password=Blah; Trusted_Connection=True;";
using (SqlConnection cnn = new SqlConnection(connectionString))
{
sql = "INSERT INTO JSON_DATA (JSONROW) VALUES(@data)";
cnn.Open();
using (SqlCommand cmd = new SqlCommand(sql, cnn))
{
String payload = "";
String nestpayload = "";
int nests = 0;
String json = document.ToString();
/*first lets do some housekeeping on our payload; double closing curly braces need to be escaped (with curly braces!) in order to keep them in the string.*/
json = json.Replace("\\", "");
int i = json.Length;
//return new SqlString(json);
while (i > 1)
{
/*find the first closing "}" in the string and then check to see if there are more than one.
We need to read the data up to each closing brace, pull off that substring and process it for each iteration until the string is gone.*/
int closingbrace = json.IndexOf("}"); //First closing brace
int nextbrace = Math.Max(0, json.IndexOf("{", closingbrace)); //Next opening brace
String ChkVal = json.Substring(closingbrace + 1, Math.Max(1, nextbrace - closingbrace)); //+1 to ignore the 1st closing brace
int checks = Math.Max(0, ChkVal.Length) - Math.Max(0, ChkVal.Replace("}", "").Length);
payload = json.Substring(0, Math.Max(0, (json.IndexOf("}") + 1)));
/*Remove the payload from the string*/
json = json.Substring(payload.Length + 1);
/*"nests" is how many nested levels excluding the opening brace for the closing brace we found.*/
nests = (payload.Length - payload.Replace("{", "").Length);
/*If we have more then one nest level check to see if any of them go with the payload*/
if (nests > 1)
{
/*Break out the nested section and remove it from the payload.*/
nestpayload = payload.Substring(0, payload.LastIndexOf("{"));
payload = payload.Substring(payload.LastIndexOf("{"), payload.Length - payload.LastIndexOf("{"));
while (nests > 1)
{
if (checks > 0) //# of right braces in payload equals number of left-side nests go with the payload
{
// payload = nestpayload.Substring(Math.Max(0, nestpayload.LastIndexOf("{")), Math.Max(0, nestpayload.Length) - Math.Max(0, (nestpayload.LastIndexOf("{")))) + payload;//The second Math.Max defaults to 1; if we got here there is at minimum one "{" character in the substring
payload = nestpayload.Substring(nestpayload.LastIndexOf("{")) + payload;
nestpayload = nestpayload.Substring(0, Math.Max(0, Math.Max(0, nestpayload.LastIndexOf("{"))));
checks--;
nests--;
}
else
{
/*If we got here there are no more pieces of the nested data to append to the payload.
We use an array and string.split to keep the nest ordering correct.*/
string[] OrderedNest = nestpayload.Split('{');
for (int s = 0; s < OrderedNest.Length; s++)
{
if (OrderedNest[s] != "")
{
cmd.Parameters.AddWithValue("@data", "{" + OrderedNest[s].Replace(":", "}"));
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
}
}
//cmd.Parameters.AddWithValue("@data", nestpayload.Substring(Math.Max(0,nestpayload.LastIndexOf("{"))).Replace(":","}"));
//cmd.Parameters.AddWithValue("@data", OrderedNest[1].Replace(":","}")+OrderedNest[2]);
// cmd.ExecuteNonQuery();
//cmd.Parameters.Clear();
//nests = Math.Max(0, nests - 1);
nests = 0;
//nestpayload = nestpayload.Substring(0, Math.Max(0, Math.Max(0,nestpayload.LastIndexOf("{"))));
}
}
}
/*At the very end payload will be a single "}"; check for this and discard the last row*/
if (payload != "}")
{
cmd.Parameters.AddWithValue("@data", new SqlChars(payload));
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
}
/*Get the new string length*/
i = json.Length;
payload = "";
}
}
}
//-----
/* }
catch (Exception e)
{
return e.ToString();
}*/
}
// Close up everything...
dataStream.Close();
}
resp.Close();
// .. and return the output to the caller.
}//end using
return ("Finished");
}
catch (WebException e)
{
throw e;
}
}
}
最佳答案
这里存在几个问题,其中最重要的一个问题是您似乎已将“ sa”密码发布到了此处的公共互联网上。这是我看到的代码问题:
尽管可以在SQLCLR中进行Web服务调用,但这绝对是一个高级话题,充满了陷阱。这不是SQLCLR的新手/初学者应该做的事情,它本身已经是常规.NET编程的细微差别。
摆脱SqlPipe
行和其上方的注释行。函数不会通过SqlPipe
将数据传递回调用方;用于存储过程。
您可能不应该使用WebRequest
document
应该是string
,而不是SqlString
。您永远不会返回document
,而只会将其转换回string
,因此就应该如此。
使用HttpWebRequest
代替WebRequest
。这样,您就不必偶尔将其转换为HttpWebRequest
。
请勿将SqlString
输入参数转换为string
(例如Convert.ToString(uri)
)。所有Sql*
类型都有一个Value
属性,该属性返回本机.NET类型的值。因此,只需使用uri.Value
,依此类推。
不要通过NULL
检查Convert.ToString(username) != null
输入。所有Sql*
类型都有一个IsNull
属性可以检查。因此,请使用!username.IsNull
。
在保持远程HttpWebRequest
连接打开的同时,请勿进行所有文本处理(尤其是与另一个系统联系以进行逐行插入的处理)。在using (WebResponse resp = req.GetResponse())
中唯一要做的就是填充document
变量。直到您不在最外面的document
之外,才对using()
的内容进行任何处理。
不要单独插入(即while (i > 1)
循环)。他们甚至都没有交易。如果在文档中间出现错误,则将加载部分数据(除非可以执行此过程)。
始终对数据库对象进行模式限定。意思是,JSON_DATA
应该是dbo.JSON_DATA
(或者如果不是dbo
,则使用任何模式)。
在您的connectionString
中,您同时具有ID /密码和Trusted_Connection
。不要同时使用这两个选项,因为它们是互斥的选项(如果同时使用,则ID /密码将被忽略,仅使用Trusted_Connection
)。
请,请不要以sa
登录或让您的应用程序以sa
登录。那只是在乞求一场灾难。
您要连接到的SQL Server实例与运行此SQLCLR对象的实例不同吗?如果是同一实例,最好将其更改为SqlProcedure
,以便可以将Context_Connection=True;
用作连接字符串。这是进程内连接,它附加到从其进行调用的会话。
不要使用Parameters.AddWithValue()
。馊主意。使用特定的适当数据类型创建SqlParameter。然后通过Parameters
将is添加到Add()
集合。
可能还有其他问题,但这是显而易见的问题。正如我在第一点所说的那样,您可能在这里过头了。不要试图成为消极的,而只是想避免另一种不良的SQLCLR实现,这通常会导致对此功能非常有用的消极看法。如果要继续这样做,请首先对SQLCLR的工作方式,最佳实践等进行更多研究。一个不错的起点是我在SQL Server Central上针对该主题编写的一系列文章:Stairway to SQLCLR。
或者,另一个选择是使用SQL# SQLCLR库的完整版(我写的)中提供的INET_GetWebPages SQLCLR TVF。这个选项不是免费的,但是它允许您简单地安装Web请求片段,然后只需要在SQLCLR标量UDF中单独解析返回的文档(即使您执行Web请求,这也是最好的方法)函数/存储过程)。实际上,如果要在同一SQL Server实例中插入表,则可以为文档解析器创建SQLCLR TVF,并使用OrderedNest
将每个yield return
值传递回(以将结果流回)并用作如下:
DECLARE @JSON NVARCHAR(MAX);
SELECT @JSON = [content]
FROM SQL#.INET_GetWebPages(@uri, .....);
INSERT INTO dbo.JSON_DATA (JSONROW)
SELECT [column_name]
FROM dbo.MyBrokenJsonFixerUpper(@JSON);
关于c# - SQL Assembly WebResponse和字符串解析非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50420129/
我正在尝试使用 C# 和 WebRequest 从 Internet 获取一个大文件。到目前为止,我拥有的所有其他东西都工作正常,但似乎我得到的响应中间的某些部分被删除了。我尝试打印出 respons
我正在尝试编写一个简单的程序来从网站返回状态代码。当前使用 HttpWebRequest 和 HttpWebResponse 类。然而,它们的工作方式对我来说似乎很糟糕,只有在 200/OK 时才会返
我目前正在研究一个帮助我创建带有 cookie 和 POST 参数的 WebRequest 的类。但是 response.cookies 总是空的。我如何获取返回的 cookie 并将它们与下一个请求
所以我正在制作一个程序,它几乎可以生成批量 HttpWebRequests。在这个程序中,速度是主要的。如果我能找到将 HttpWebRequests 增加一毫秒的方法,那就太好了。 好吧,我的问题是
网站上有一个 PHP 脚本。我还有一个 C# winforms 程序,它使用 WebRequest/WebResponse 方法发送 POST 消息。 此 PHP 脚本连接到 mysql 数据库,获取
使用 C#,我需要确定开始从 WebRequest 接收响应所需的时间(目前,我不担心下载完整响应所需的时间)。 据我所知,为此我需要使用 WebRequest 的异步方法。这是我想出的: publi
我们正在将我们的解决方案之一移植到 PCL,但在 NET 框架基类库的受支持类和属性方面面临很多问题。为了使相同的功能在不同的平台上工作,我们实现了 WebClient,但我们在 WebResporn
我正在尝试使用 Web 服务将数组返回到我的 GUI,但我不知道如何从 WebResponse 中实际提取数组。 这是 GUI 中调用 Web 服务的方法: public static ArrayLi
我正在使用 C# 开发 Windows 应用商店应用程序,我是这个平台的新手(我主要从事 IOS 和 Android 方面的工作)。 我有一个简单的异步方法可以从远程服务器下载原始数据。它工作正常,除
我一直在 F# 交互式 session 中尝试一些基本的 HTTP 请求响应操作,以尝试更好地感受这门语言。这里的一切似乎都按预期工作,除了当我获得 HTTP 请求的响应流时,我似乎永远无法从中读取任
WebResponse response; try { HttpWebRequest request = (HttpWebRequest)WebRequest.Crea
我知道这是一个菜鸟问题,但只是想知道 GetResponseStream() 是否可以在任何情况下返回 null? 最佳答案 好吧,这有点取决于具体的子类 - 但我从未见过任何这样做的子类,而且它没有
我有一个 .Net Framework #4.0 应用程序,它使用 WebRequest/WebResponse 类发出大量 Web 请求,因为我发现它有内存泄漏(或者我做错了什么)我写了一些简单的小
通常,人们会编写类似这样的代码来使用 WebRequest 下载一些数据。 using(WebResponse resp = request.GetResponse()) // WebRequest
private void RespCallback(IAsyncResult asynchronousResult) { try { WebRequest myWebR
我在 C# 中有一个函数,它通过从路由器页面检索 64b XML 来获取 Internet 的状态 public bool isOn() { HttpWebRe
从 WebResponse 获取文件(在本例中为 .PDF,但任何文件都可以)并将其放入 MemoryStream 的最佳方法是什么?使用 WebResponse 中的 .GetResponseStr
调用初始 HttpWebResponse.GetResponseStream() 并读取流后,该流已完成且无法重用。 我遇到一种情况,我需要检查响应的内容,如果它是特定数据,则获取另一个页面,然后将新
我使用 MVC4 Web API 创建了一个 RESTful 网络服务。如果出现问题,我将抛出 WebException。 throw new WebException("Account not fo
我正在尝试编写一个单元测试,其中我的 sut (authMock) 的依赖项应该抛出一个具有特定响应的 Webexception(将在 sut 中相应地解析的 json)。但是,我无法像这样使用 Mo
我是一名优秀的程序员,十分优秀!