通过 SQLCLR 使用 Rest API 并通过 SqlPipe 发送结果
Consuming Rest API via SQLCLR and sending result via SqlPipe
我正在尝试通过 CLR 存储过程使用 rest/json get api。我的问题是我只得到一条(最后一条)记录。
这是我的代码:
public partial class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void FrtApiJsonGet ()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("some site");
var byteArray = Encoding.ASCII.GetBytes("login:password");
request.Method = "GET";
request.Headers.Add(HttpRequestHeader.Authorization, "Basic " +
Convert.ToBase64String(byteArray));
using(HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream receiveStream = response.GetResponseStream())
{
using (StreamReader readStream = new StreamReader(receiveStream,
Encoding.UTF8))
{
string strContent = readStream.ReadToEnd();
string value1 = string.Empty;
string value2 = string.Empty;
string value3 = string.Empty;
string value4 = string.Empty;
SqlPipe pipe = SqlContext.Pipe;
SqlMetaData[] cols = new SqlMetaData[4];
cols[0] = new SqlMetaData("value1", SqlDbType.NVarChar, 50);
cols[1] = new SqlMetaData("value2", SqlDbType.NVarChar, 50);
cols[2] = new SqlMetaData("value3", SqlDbType.NVarChar, 50);
cols[3] = new SqlMetaData("value4", SqlDbType.NVarChar, 50);
SqlDataRecord record = new SqlDataRecord(cols);
pipe.SendResultsStart(record);
var strArray = strContent.Split(new string[] { "{,}" },
StringSplitOptions.None);
foreach(var str in strArray)
{
var subArray = str.Split(',');
foreach (var substr in subArray)
{
if (substr.Contains("\"value1\""))
value1 = substr.Split('\"')[3];
if (substr.Contains("\"value2\""))
callKey = substr.Split('\"')[3];
if (substr.Contains("\"value3\""))
callPhase = substr.Split('\"')[3];
if (substr.Contains("\"value4\""))
callresult = substr.Split('\"')[3];
}
record.SetSqlString(0, new SqlString(value1));
record.SetSqlString(1, new SqlString(value2));
record.SetSqlString(2, new SqlString(value3));
record.SetSqlString(3, new SqlString(value4));
pipe.SendResultsRow(record);
value1 = string.Empty;
value2 = string.Empty;
value3 = string.Empty;
value4 = string.Empty;
}
pipe.SendResultsEnd();
}
}
}
}
}
我知道 api 有效,如果我在控制台应用程序中尝试没有 sqlpipe 的相同代码,它 returns 一个值列表...但是当用作 clr 存储过程时,我得到只有一个(最后)记录。
就 SendResultsStart
、SendResultsRow
和 SendResultsEnd
的处理而言,总体结构似乎是正确的。
下一个要检查的地方是循环本身。很可能最初的 Split
并没有像您认为的那样发生。您应该在 var subArray = str.Split(',');
之前添加一个 pipe.Send(str);
,这样您就可以看到响应是如何被分割成行的。这会将每个块发送到 "Messages" 选项卡,以便您可以对其进行调试(与通过 T-SQL 执行 PRINT
相同)。
我正在尝试通过 CLR 存储过程使用 rest/json get api。我的问题是我只得到一条(最后一条)记录。
这是我的代码:
public partial class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void FrtApiJsonGet ()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("some site");
var byteArray = Encoding.ASCII.GetBytes("login:password");
request.Method = "GET";
request.Headers.Add(HttpRequestHeader.Authorization, "Basic " +
Convert.ToBase64String(byteArray));
using(HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream receiveStream = response.GetResponseStream())
{
using (StreamReader readStream = new StreamReader(receiveStream,
Encoding.UTF8))
{
string strContent = readStream.ReadToEnd();
string value1 = string.Empty;
string value2 = string.Empty;
string value3 = string.Empty;
string value4 = string.Empty;
SqlPipe pipe = SqlContext.Pipe;
SqlMetaData[] cols = new SqlMetaData[4];
cols[0] = new SqlMetaData("value1", SqlDbType.NVarChar, 50);
cols[1] = new SqlMetaData("value2", SqlDbType.NVarChar, 50);
cols[2] = new SqlMetaData("value3", SqlDbType.NVarChar, 50);
cols[3] = new SqlMetaData("value4", SqlDbType.NVarChar, 50);
SqlDataRecord record = new SqlDataRecord(cols);
pipe.SendResultsStart(record);
var strArray = strContent.Split(new string[] { "{,}" },
StringSplitOptions.None);
foreach(var str in strArray)
{
var subArray = str.Split(',');
foreach (var substr in subArray)
{
if (substr.Contains("\"value1\""))
value1 = substr.Split('\"')[3];
if (substr.Contains("\"value2\""))
callKey = substr.Split('\"')[3];
if (substr.Contains("\"value3\""))
callPhase = substr.Split('\"')[3];
if (substr.Contains("\"value4\""))
callresult = substr.Split('\"')[3];
}
record.SetSqlString(0, new SqlString(value1));
record.SetSqlString(1, new SqlString(value2));
record.SetSqlString(2, new SqlString(value3));
record.SetSqlString(3, new SqlString(value4));
pipe.SendResultsRow(record);
value1 = string.Empty;
value2 = string.Empty;
value3 = string.Empty;
value4 = string.Empty;
}
pipe.SendResultsEnd();
}
}
}
}
}
我知道 api 有效,如果我在控制台应用程序中尝试没有 sqlpipe 的相同代码,它 returns 一个值列表...但是当用作 clr 存储过程时,我得到只有一个(最后)记录。
就 SendResultsStart
、SendResultsRow
和 SendResultsEnd
的处理而言,总体结构似乎是正确的。
下一个要检查的地方是循环本身。很可能最初的 Split
并没有像您认为的那样发生。您应该在 var subArray = str.Split(',');
之前添加一个 pipe.Send(str);
,这样您就可以看到响应是如何被分割成行的。这会将每个块发送到 "Messages" 选项卡,以便您可以对其进行调试(与通过 T-SQL 执行 PRINT
相同)。