使用CLR表值函数进行Web服务调用

时间:2016-03-08 19:59:16

标签: c# user-defined-functions sqlclr

我试图整理一些TVR,并且我一直收到以下错误:

  

从用户定义的表值函数获取新行时发生错误:

     

System.InvalidCastException:无法转换类型' System.Char'的对象。输入' ResultRow'。

     

CLR.WorkFunctions.FillRow的System.InvalidCastException(Object resultsObj,   的SqlString&安培; policyURL,SqlString& fileCachePath,SqlString&身份,   的SqlString&安培; format,SqlString& userName,SqlString&密码,SqlString&数据)

我尝试调用对传递的数据执行某些操作的Web服务,然后将返回的值加载到枚举器中。但是,如上所示,我反复输入打字错误,此时我不确定原因。我的想法是因为我试图用字符串而不是SqlStrings来填充行,所以我改变了。但是,Web服务只接受参数作为字符串,因此我必须在Web服务调用上转换它们。这是我的代码:

public class WorkFunctions
    {
        private class ResultRow
        {
            public string PolicyURL;
            public string FileCachePath;
            public string Identity;
            public string Format;
            public string UserName;
            public string Password;
            public string Data;
        }
    [Microsoft.SqlServer.Server.SqlFunction(
               FillRowMethodName = "FillRow",
               TableDefinition = "policyName nvarchar(500), fileCache nvarchar(500), 
               identity nvarchar(500), format nvarchar(500), userName nvarchar(500), 
               password nvarchar(500), data nvarchar(500)")]
            public static IEnumerable Work(SqlString serviceURL, SqlString policyURL, SqlString fileCachePath, SqlString identity, SqlString format, SqlString userName, SqlString password, SqlString data)
           {
              IEnumerable values;

              try
                {
                    CLR.Work.WorkService.WorkMethods workMethods = new CLR.Work.WorkService.WorkMethods();
                    workMethods.Url = Convert.ToString(serviceURL);
                    values = workMethods.Work(Convert.ToString(policyURL), Convert.ToString(identity), Convert.ToString(format), Convert.ToString(userName), Convert.ToString(password), Convert.ToString(fileCachePath), Convert.ToString(data));
                }
              catch (Exception ex)
                {
                   return "Failed to return data";
                }

              return values;
          }

            public static void FillRow(Object resultObj, 
              out SqlString policyURL, out SqlString fileCachePath, 
              out SqlString identity, out SqlString format, 
              out SqlString userName, out SqlString password, 
              out SqlString data)
                 {
                   ResultRow resultRow = (ResultRow)resultObj;

                   policyURL = new SqlString(resultRow.PolicyURL);
                   fileCachePath = new SqlString (resultRow.FileCachePath);
                   identity = new SqlString (resultRow.Identity);
                   format = new SqlString (resultRow.Format);
                   userName = new SqlString (resultRow.UserName);
                   password = new SqlString (resultRow.Password);
                   data = new SqlString (resultRow.Data);

                }
      }
}

这是我第一次与TVF合作,而我在此时可能导致此问题的方面有点不知所措。如果有人能提出一些想法,我会很感激。

感谢。

1 个答案:

答案 0 :(得分:0)

最直接问题的最可能原因是workMethods.Work()方法不会返回与您定义为ResultRow的类型相同的类型。正在返回由workMethods.Work()返回并被分配给values的任何内容作为结果,并将其作为类型Object的第一个参数发送到FillRowMethod。除此之外,您应该删除IEnumerable values;return values;行,然后执行以下操作:

ResultRow _Row = new ResultRow();

...

_Row = workMethods.Work(...);

yield return _Row;

此外,无需在任何Convert.ToString()输入参数上使用SqlString。所有Sql*类型都具有.Value属性,该属性返回预期的.NET类型。所以只需使用serviceURL.ValuepolicyURL

最后,为什么输出字段与输入参数几乎相同?看起来像一个奇怪的签名。

P.S。如果您想要/需要有关使用SQLCLR的更多信息,我将在SQL Server Central上撰写关于此主题的系列文章:Stairway to SQLCLR。该网站确实需要免费注册才能查看其内容(但由于各种文章和论坛中有大量信息,因此非常值得。)