我有一个C#(.NET框架4.7.2)脚本来执行一些跟踪代码的自定义读取,我正try 使用它来创建一个SQL(V14.0.3445.2)表值函数.C#FillRow方法如下所示:

public partial class UserDefinedFunctions
{
    [SqlFunction(DataAccess = DataAccessKind.Read, FillRowMethodName = "Read_Trace",
    TableDefinition =
    " Site NVARCHAR(3)" +
    ",Line TINYINT" +
    ",Shift NVARCHAR(2)" +
    ",ProductionDate DATETIME2(0)" +
    ",ProductionTime NVARCHAR(5)" +
    ",DayName NVARCHAR(9)" +
    ",Perfect_Trace BIT" +
    ",NWFGenerated_Trace BIT" +
    ",Altered_Trace BIT")]
public static IEnumerable Read_Trace([SqlFacet(MaxSize = 255)] SqlChars customer, [SqlFacet(MaxSize = 255)] SqlChars trace)
{
    var trc = trace.ToString();
    RegexList regexList = GetRegexList(customer.ToString(), trace.ToString());

    return new List<TraceContents>
    {
        new TraceContents
        {
            Site = GetValue(regexList.Site_Regex, trc),
            Line = SqlInt16.Parse(new string(GetValue(regexList.Line_Regex, trc).Where(char.IsNumber).ToArray())),
            Shift = GetValue(regexList.Shift_Regex, trc),
            ProductionDate = JulianToDate(GetValue(regexList.Date_Regex, trc)),
            ProductionTime = GetValue(regexList.Time_Regex, trc),
            DayName = GetValue(regexList.Day_Regex, trc),
            Perfect_Trace = regexList.Perfect_Trace,
            NWFGenerated_Trace = regexList.NWFGenerated_Trace,
            Altered_Trace = regexList.Altered_Trace
        }
    };
}

我使用以下SQL脚本将其转换为函数:

DROP ASSEMBLY if exists CLR_Functions;
CREATE ASSEMBLY CLR_Functions
FROM 'C:\Temp\Functions.dll'
GO

CREATE FUNCTION fn_ReadTraceCode(@InvoiceAccount NVARCHAR(255), @Trace NVARCHAR(255)) RETURNS
TABLE (
     [Site] NVARCHAR(3)
    ,[Line] TINYINT
    ,[Shift] NVARCHAR(2)
    ,[ProductionDate] DATETIME2(0)
    ,[ProductionTime] NVARCHAR(5)
    ,[DayName] NVARCHAR(9)
    ,[Perfect_Trace] BIT
    ,[NWFGenerated_Trace] BIT
    ,[Altered_Trace] BIT)
AS EXTERNAL NAME CLR_Functions.UserDefinedFunctions.Read_Trace
GO

这两个脚本的参数数量匹配,我认为这是必需的,但当我运行SQL脚本时,我得到以下错误:

消息6208,级别16,状态1,过程FN_ReadTraceCode,第2行[批次 Start Line 4]Create Function失败,因为参数计数 FillRow方法应该比 表值CLR函数.

我不知道我做错了什么--我遵循了逐步指南(如this),但没有找到任何关于需要额外参数的东西,事实上,在此之前我曾经做过一个CLR函数,似乎不需要额外的参数……网上对这个问题的唯一答案是,在一次事件中,该函数的return列之间存在真正的不匹配,这加剧了我的困惑.

你能帮我停止这个错误的出现,这样我的函数就可以编译了吗?如果需要,我可以发布完整的代码,但我认为问题出在上面列出的FillRow方法上.

推荐答案

您的代码与SQLCLR期望的代码完全不匹配.如果是look at the docs,则需要two个函数:一个用于返回IEnumerable,另一个用于填充行并具有一组out个参数来完成此操作.

[SqlFunction(
    DataAccess = DataAccessKind.Read,
    FillRowMethodName = nameof(Read_Trace_Fill),
    TableDefinition =
    " Site NVARCHAR(3)" +
    ",Line TINYINT" +
    ",Shift NVARCHAR(2)" +
    ",ProductionDate DATETIME2(0)" +
    ",ProductionTime NVARCHAR(5)" +
    ",DayName NVARCHAR(9)" +
    ",Perfect_Trace BIT" +
    ",NWFGenerated_Trace BIT" +
    ",Altered_Trace BIT")]
public static IEnumerable Read_Trace([SqlFacet(MaxSize = 255)] SqlChars customer, [SqlFacet(MaxSize = 255)] SqlChars trace)
{
    var trc = trace.ToString();
    RegexList regexList = GetRegexList(customer.ToString(), trace.ToString());

    return new List<TraceContents>
    {
        new TraceContents
        {
            Site = GetValue(regexList.Site_Regex, trc),
            Line = SqlInt16.Parse(new string(GetValue(regexList.Line_Regex, trc).Where(char.IsNumber).ToArray())),
            Shift = GetValue(regexList.Shift_Regex, trc),
            ProductionDate = JulianToDate(GetValue(regexList.Date_Regex, trc)),
            ProductionTime = GetValue(regexList.Time_Regex, trc),
            DayName = GetValue(regexList.Day_Regex, trc),
            Perfect_Trace = regexList.Perfect_Trace,
            NWFGenerated_Trace = regexList.NWFGenerated_Trace,
            Altered_Trace = regexList.Altered_Trace
        }
    };
}

    public static void Read_Trace_Fill(
    Object traceObj,
    out string Site,
    out byte Line,
    out string Shift,
    out DateTime? ProductionDate,
    out string ProductionTime,
    out string DayName,
    out bool Perfect_Trace,
    out bool NWFGenerated_Trace,
    out bool Altered_Trace
)
    {
        var trace = (TraceContents)traceObj;
        Site = trace.Site;
        Line = trace.Line;
        Shift = trace.Shift;
        ProductionDate = trace.ProductionDate;
        ProductionTime = trace.ProductionTime;
        DayName = trace.DayName;
        Perfect_Trace = trace.Perfect_Trace;
        NWFGenerated_Trace = trace.NWFGenerated_Trace;
        Altered_Trace = trace.Altered_Trace;
    }

如果结果很大(即多行),那么您最终会将整个结果存储在内存中.理想情况下,您应该使用yield return来创建流IEnumerable.在本例中,您似乎只返回了一行.

Csharp相关问答推荐

亚马逊Pinpoint C# SDK

为什么xslWriter不总是按照xslWriterSet中指定的格式格式化该文档?

如何将字节数组转换为字符串并返回?

ASP.NET Core:如何在IPageFilter中注入ApplicationDbContext

如何使用C#Interop EXCEL创建度量衡

如何在毛伊岛应用程序中完美地同步视图模型和视图的加载?

NET8 MAUI并部署到真实设备上进行测试

Automapper 12.x将GUID映射到字符串

单元测试:模拟返回空

C#自定义验证属性未触发IsValid方法

如何在.NET Maui中将事件与MVVM一起使用?

使用ASP.NET MVC for Lemon Squeezy X-Signature创建散列

KeyDown从我的文本框中删除输入,如何停止?

我想根据姓氏按字母顺序对包含150行徽章编号、姓氏、名字、地址等的文件进行排序.e

如何将默认区域性更改为fr-FR而不是en-US?

为什么我在使用有效令牌的情况下仍未获授权?

Visual Studio如何使用当前的框架?

C#中COM对象的实际地址

有没有更好的方法来使用LINQ获取整行的计算组

如果图表S批注包含使用LINQ的具有特定名称的批注,我如何签入C#