通过 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 存储过程时,我得到只有一个(最后)记录。

SendResultsStartSendResultsRowSendResultsEnd 的处理而言,总体结构似乎是正确的。

下一个要检查的地方是循环本身。很可能最初的 Split 并没有像您认为的那样发生。您应该在 var subArray = str.Split(','); 之前添加一个 pipe.Send(str);,这样您就可以看到响应是如何被分割成行的。这会将每个块发送到 "Messages" 选项卡,以便您可以对其进行调试(与通过 T-SQL 执行 PRINT 相同)。