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

SSIS新手求助:如何使用SSIS解析非标准平面文件

如何用SSIS解析这种非标准平面文件

嘿,作为SSIS老玩家,这种没按规矩来的平面文件我碰过不少——从你给的片段来看,它用*划分大区块、字段靠#分隔但内部还带空格(比如日期时间),完全没法直接用SSIS自带的平面文件源搞定,得靠自定义脚本源来硬刚。下面是一步步落地的方案:

步骤1:添加脚本源组件

在Data Flow任务里拖一个脚本组件,选择作为源使用——这是我们自定义解析逻辑的核心载体。

步骤2:提前定义输出列

先根据你文件里的字段特征,在脚本组件的「输入和输出」选项卡中配置输出列。比如从你的示例里,能整理出这些常用字段(你可以按需调整):

  • RecordID:每条记录的唯一编号(比如451487、42075)
  • Code:固定编号(比如2503)
  • Value:数值字段(比如1.67、1.63999...)
  • StartDate:短日期(比如03/04/18)
  • DateTimeStamp:带时间戳的日期(比如04/04/18 14:38:00)
  • Status:状态码(比如14、2、1)
  • BlockGroup:标记这条记录属于哪个*分隔的区块

记得给每个列设置对应的数据类型(比如RecordID用字符串、Value用双精度浮点数、DateTimeStamp用日期时间类型)。

步骤3:编写C#解析逻辑(脚本编辑器)

打开脚本编辑器,在CreateNewOutputRows方法里写核心代码。思路是:先读整个文件,拆分成*分隔的区块,再把每个区块拆成单条记录,最后按#拆分字段映射到输出列。

给你一份可直接修改的示例代码:

using System;
using System.IO;
using System.Text.RegularExpressions;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
    public override void CreateNewOutputRows()
    {
        // 建议用SSIS变量传递路径,这里先硬编码示例
        string filePath = @"C:\YourTargetFile.txt";
        string fullContent = File.ReadAllText(filePath);
        
        // 用*分割成独立区块,去掉空内容
        string[] blocks = fullContent.Split(new[] { '*' }, StringSplitOptions.RemoveEmptyEntries);
        
        int blockNum = 1;
        foreach (string rawBlock in blocks)
        {
            string cleanBlock = rawBlock.Trim();
            // 用正则匹配单条记录:匹配以数字+#开头的内容,直到下一条记录开头或区块结束
            MatchCollection records = Regex.Matches(cleanBlock, @"\d+#.*?(?=\s*\d+#|$)", RegexOptions.Singleline);
            
            foreach (Match recordMatch in records)
            {
                string singleRecord = recordMatch.Value.Trim();
                string[] fields = singleRecord.Split(new[] { '#' }, StringSplitOptions.None);
                
                // 创建新输出行
                Output0Buffer.AddRow();
                
                // 映射字段,注意处理空字段(比如连续##的情况)
                if (singleRecord.StartsWith("PiF#"))
                {
                    // 处理开头的文件头记录
                    Output0Buffer.RecordID = fields[2];
                    Output0Buffer.Code = fields[3];
                    Output0Buffer.Value = !string.IsNullOrEmpty(fields[5]) ? double.Parse(fields[5]) : 0;
                    Output0Buffer.StartDate = DateTime.ParseExact(fields[7], "dd/MM/yy", null);
                    Output0Buffer.DateTimeStamp = DateTime.ParseExact(fields[8], "dd/MM/yy HH:mm:ss", null);
                    Output0Buffer.Status = int.Parse(fields[9]);
                }
                else
                {
                    // 处理普通记录,不同区块字段数可能不同,按需判断
                    Output0Buffer.RecordID = fields[0];
                    Output0Buffer.Code = fields[1];
                    if (fields.Length >= 4)
                    {
                        Output0Buffer.Value = !string.IsNullOrEmpty(fields[3]) ? double.Parse(fields[3]) : 0;
                    }
                    if (fields.Length >= 5)
                    {
                        Output0Buffer.DateTimeStamp = DateTime.ParseExact(fields[4], "dd/MM/yy HH:mm:ss", null);
                    }
                    if (fields.Length >= 6)
                    {
                        Output0Buffer.RefCode = fields[2]; // 比如0P2018R1190
                        Output0Buffer.Flag = int.Parse(fields[4]);
                    }
                }
                Output0Buffer.BlockGroup = blockNum;
            }
            blockNum++;
        }
    }
}

步骤4:必注意的细节

  • 日期格式匹配:你的日期是dd/MM/yy格式,一定要确保ParseExact里的格式字符串和实际一致,不然会报错
  • 空字段处理:文件里的连续##会分割出空字符串,转换数值/日期前要先判断是否为空
  • 变量传递路径:别硬编码文件路径,在脚本组件的「脚本」选项卡中添加只读变量,用Variables.YourVariableName获取路径,这样更灵活
  • 正则调整:如果你的记录开头不是数字,要修改正则表达式的匹配规则,保证能准确拆分每条记录
  • 异常处理:如果文件里有无效数值/日期,建议加try-catch块捕获错误,避免整个任务失败

备选简化方案(适合怕写代码的情况)

如果不想写太多脚本,也可以分步处理:

  1. 用平面文件源把整个文件读成单一行(设置行分隔符为一个不存在的字符,比如|)
  2. 用派生列或脚本组件按*拆分出各个区块
  3. 再用脚本组件把每个区块拆成单条记录和字段

不过这种方法效率不如直接用脚本源,大文件情况下不推荐。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:10:45