1

我正在尝试通过 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

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

那么,我做错了什么??

4

2 回答 2

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;
    }
}

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

于 2012-08-14T19:17:00.550 回答
1

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

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

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

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

于 2012-08-14T19:13:05.203 回答