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

SSIS中C#脚本任务未遍历全部26个文件的问题求助

问题分析与解决

你的核心问题是仅记录了上一个处理的文件,而非所有已处理文件,导致循环时来回读取最新的两个文件,无法遍历全部26个文件:

每次循环中,脚本会重新读取所有文件并按时间戳降序排列,然后取第一个不等于LastProcessedFile的文件。第一次取最新文件,第二次取次新文件,第三次又会取最新文件(因为此时LastProcessedFile是次新文件),以此类推,循环26次就只会重复读取这两个文件。

修复步骤

1. 调整包变量

将原有的User::LastProcessedFile变量替换为User::ProcessedFiles(字符串类型,初始值为空),用来存储所有已处理的文件路径(用分号;分隔)。

2. 修改脚本任务代码

替换现有脚本逻辑,改为跟踪所有已处理文件,每次从剩余未处理文件中选取下一个:

public void Main()
{
    bool fireAgain = true;
    string sourceFolder = Dts.Variables["User::SourceFolder"].Value.ToString();
    string fileExtension = Dts.Variables["User::FileExtension"].Value.ToString();
    string processedFiles = Dts.Variables["User::ProcessedFiles"].Value.ToString();

    // 把已处理文件转为集合,快速判断是否已处理
    HashSet<string> processedSet = new HashSet<string>();
    if (!string.IsNullOrEmpty(processedFiles))
    {
        foreach (string file in processedFiles.Split(';'))
        {
            processedSet.Add(file.Trim());
        }
    }

    string[] files = Directory.GetFiles(sourceFolder, "*" + fileExtension);
    Dictionary<string, DateTime> fileTimestamps = new Dictionary<string, DateTime>();

    foreach (string file in files)
    {
        // 跳过已处理的文件
        if (processedSet.Contains(file))
            continue;

        string fileName = Path.GetFileNameWithoutExtension(file);
        // 避免文件名长度不足导致报错
        if (fileName.Length < 14)
            continue;

        string fileTimestamp = fileName.Substring(fileName.Length - 14, 14);
        DateTime timestamp;
        if (DateTime.TryParseExact(fileTimestamp, "yyyyMMddHHmmss", null, System.Globalization.DateTimeStyles.None, out timestamp))
        {
            fileTimestamps.Add(file, timestamp);
        }
    }

    // 按时间戳降序,取第一个未处理的文件
    var nextFile = fileTimestamps.OrderByDescending(x => x.Value).FirstOrDefault();

    if (nextFile.Key != null)
    {
        Dts.Variables["User::LatestFile"].Value = nextFile.Key;
        // 更新已处理文件列表
        if (string.IsNullOrEmpty(processedFiles))
        {
            Dts.Variables["User::ProcessedFiles"].Value = nextFile.Key;
        }
        else
        {
            Dts.Variables["User::ProcessedFiles"].Value = processedFiles + ";" + nextFile.Key;
        }

        // 输出调试日志,方便排查
        Dts.Events.FireInformation(0, "Script Task", $"Processing file: {nextFile.Key}", string.Empty, 0, ref fireAgain);
        Dts.TaskResult = (int)ScriptResults.Success;
    }
    else
    {
        MessageBox.Show("No new files left to process.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
        Dts.TaskResult = (int)ScriptResults.Failure;
    }
}

3. 调整Foreach循环配置

不要设置固定26次循环,改为循环直到脚本任务返回Failure:

  • 将Foreach循环的“EvalExpression”设置为检查脚本任务的执行结果,或者使用“For Loop”容器,设置循环条件为@[User::ProcessedFiles]未包含所有文件,或直接循环直到脚本任务失败(无文件可处理)。

4. 优化数据流分支(可选)

如果26个文件的结构一致,不需要保留26个数据流分支,只用一个数据流任务即可,每次循环加载User::LatestFile指向的文件。如果文件结构不同,需在数据流分支前添加“优先约束”,根据LatestFile的文件名判断执行对应分支。

调试技巧

  • 在脚本中添加Dts.Events.FireInformation输出日志,可在SSIS的“执行结果”窗口查看每次循环的处理文件信息。
  • 给脚本任务设置断点,调试时查看processedSet、fileTimestamps等变量的内容,确认逻辑是否符合预期。

内容的提问来源于stack exchange,提问作者Manoj Sai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 03:17:41