You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CLR表值函数FillRow方法参数数量不匹配错误排查

问题根源

你错误地将返回IEnumerable的主函数指定为FillRowMethodName的目标方法。SQL Server要求CLR表值函数必须包含两个核心部分:

  • 主函数:负责生成要返回的数据集(返回IEnumerable类型)
  • FillRow方法:负责将IEnumerable中的每个对象拆解为SQL表的列,它的参数数量必须等于表列数 + 1(多出来的参数是要拆解的对象实例)

你的代码把主函数当成了FillRow方法,导致签名不匹配,触发了错误提示。

修正后的C#代码

首先补全TraceContents类定义(原代码未给出,必须包含才能编译),然后添加符合要求的FillRow方法,并修正主函数的SqlFunction属性:

// 补全TraceContents类,对应输出表的结构
public class TraceContents
{
    public string Site { get; set; }
    public short Line { get; set; }
    public string Shift { get; set; }
    public DateTime ProductionDate { get; set; }
    public string ProductionTime { get; set; }
    public string DayName { get; set; }
    public bool Perfect_Trace { get; set; }
    public bool NWFGenerated_Trace { get; set; }
    public bool Altered_Trace { get; set; }
}

public partial class UserDefinedFunctions
{
    // 主函数:负责生成数据,FillRowMethodName指向专门的FillRow方法
    [SqlFunction(DataAccess = DataAccessKind.Read, 
                 FillRowMethodName = "Fill_Read_TraceRow", // 修正为正确的FillRow方法名
                 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(), trc);

        return new List<TraceContents>
        {
            new TraceContents
            {
                Site = GetValue(regexList.Site_Regex, trc),
                Line = short.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
            }
        };
    }

    // 新增FillRow方法:参数1是TraceContents实例,后续参数对应表的每一列(out修饰)
    public static void Fill_Read_TraceRow(object rowObj, 
                                         out SqlString Site,
                                         out SqlByte Line,
                                         out SqlString Shift,
                                         out SqlDateTimeOffset ProductionDate,
                                         out SqlString ProductionTime,
                                         out SqlString DayName,
                                         out SqlBoolean Perfect_Trace,
                                         out SqlBoolean NWFGenerated_Trace,
                                         out SqlBoolean Altered_Trace)
    {
        TraceContents row = (TraceContents)rowObj;
        
        Site = string.IsNullOrEmpty(row.Site) ? SqlString.Null : new SqlString(row.Site);
        Line = new SqlByte((byte)row.Line);
        Shift = string.IsNullOrEmpty(row.Shift) ? SqlString.Null : new SqlString(row.Shift);
        ProductionDate = new SqlDateTimeOffset(row.ProductionDate);
        ProductionTime = string.IsNullOrEmpty(row.ProductionTime) ? SqlString.Null : new SqlString(row.ProductionTime);
        DayName = string.IsNullOrEmpty(row.DayName) ? SqlString.Null : new SqlString(row.DayName);
        Perfect_Trace = row.Perfect_Trace;
        NWFGenerated_Trace = row.NWFGenerated_Trace;
        Altered_Trace = row.Altered_Trace;
    }

    // 保留你原有的GetValue、GetRegexList、JulianToDate方法
    private static string GetValue(Regex regex, string input) => /* 你的原有实现 */;
    private static RegexList GetRegexList(string customer, string trace) => /* 你的原有实现 */;
    private static DateTime JulianToDate(string julianDate) => /* 你的原有实现 */;
}

// 补全RegexList类定义
public class RegexList
{
    public Regex Site_Regex { get; set; }
    public Regex Line_Regex { get; set; }
    public Regex Shift_Regex { get; set; }
    public Regex Date_Regex { get; set; }
    public Regex Time_Regex { get; set; }
    public Regex Day_Regex { get; set; }
    public bool Perfect_Trace { get; set; }
    public bool NWFGenerated_Trace { get; set; }
    public bool Altered_Trace { get; set; }
}
关键说明
  1. FillRow方法签名要求:
    • 第一个参数必须是object类型(对应IEnumerable中的元素,后续强制转换为实际类型)
    • 后续每个参数对应SQL表的一列,必须用out修饰,类型要匹配SQL类型的CLR映射(比如SQL的TINYINT对应SqlByte,BIT对应SqlBoolean)
    • 参数总数 = 表列数 + 1(这就是错误提示中“多1个参数”的原因)
  2. 主函数与FillRow的关联:通过SqlFunction属性的FillRowMethodName指定FillRow方法的名称,两者必须在同一个类中
  3. 空值处理:在FillRow方法中要处理.NET空值,转换为SQL对应的Sql*Null值,避免返回无效数据
后续操作
  1. 用修正后的代码重新编译生成Functions.dll
  2. 重新执行你原有的SQL脚本(无需修改SQL部分)

内容的提问来源于stack exchange,提问作者High Plains Grifter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 22:37:14