为<>创建功能返回值的T-SQL和CLR类型不匹配

时间:2012-08-14 18:39:40

标签: c# sql tsql sqlclr sql-types

我正在尝试通过CRL集成创建SQL函数,但我遇到以下错误:

  

“GetWSClient”的CREATE FUNCTION失败,因为返回值的T-SQL和CLR类型不匹配。

我正在尝试在我的dll中使用WebService,然后将其作为SQL Server中的程序集进行集成。

我的C#代码是:

namespace InternalLists
{
    public class UserDefinedFunctions
    {

      [Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.Read, Name = "WSClient", FillRowMethodName = "Fill_WSClient",
        TableDefinition = "Name nvarchar(255)")]
       public static DataSet WSClient(SqlString url, SqlString idClient)
       {
           WSInternalList.CLIENTS client = new WSInternalList.CLIENTS();
           client.Url = url.ToString();
           return client.WM_CLIENT(idClient.ToString());
       }

       public static void Fill_WSClient(object ProductObj, out SqlString Name)
       {
           DataRow row = (DataRow)ProductObj;
           Name = new SqlString(row["VWSDN_NAME"].ToString());
       }
    }
}

我的SQL代码是:

CREATE FUNCTION [dbo].[GetWSClient](@url nvarchar(255), @idClient nvarchar(255))
RETURNS  TABLE (
Name nvarchar(255) NULL
)
EXTERNAL NAME [InternalLists].[InternalLists.UserDefinedFunctions].[WSClient]
GO

我已经看到this回答,但是我将我的函数声明为DataSet返回类型,并且我知道我的WS正在返回DataSet结果。

那么,我做错了什么?

2 个答案:

答案 0 :(得分:2)

您正在创建CLR 表值函数。在http://msdn.microsoft.com/en-us/library/ms131103.aspx的文档中,这是一个示例:

using System;
using System.Data.Sql;
using Microsoft.SqlServer.Server;
using System.Collections;
using System.Data.SqlTypes;
using System.Diagnostics;

public class TabularEventLog
{
    [SqlFunction(FillRowMethodName = "FillRow")]
    public static IEnumerable InitMethod(String logname)
    {
        return new EventLog(logname).Entries;
    }

    public static void FillRow(Object obj, out SqlDateTime timeWritten, out SqlChars message, out SqlChars category, out long instanceId)
    {
        EventLogEntry eventLogEntry = (EventLogEntry)obj;
        timeWritten = new SqlDateTime(eventLogEntry.TimeWritten);
        message = new SqlChars(eventLogEntry.Message);
        category = new SqlChars(eventLogEntry.Category);
        instanceId = eventLogEntry.InstanceId;
    }
}

您需要返回IEnumerableIEnumerable<T>。运行时将负责枚举IEnumerable,将每个枚举对象传递给Fill Row方法(作为上面示例中的第一个参数Object obj)并注意将其映射到可以通过TDS喷射到客户端,客户端将根据它将其转换为结果集。

答案 1 :(得分:1)

T-SQL表数据类型与DataSet数据类型不同。 SQLCLR程序集中的UDF需要返回IEnumerable类型,而DataSet不实现IEnumerable。

您可以将函数转换为返回IListSource.GetList(),它实现了IEnumerable,如:

return ((IListSource)client.WM_CLIENT(idClient.ToString())).GetList();

标准警告适用 - 未经测试 - 但也许这会让您朝着正确的方向前进。祝福!