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

在SSIS脚本组件中用C#将多行扁平文件合并为单条记录

解决SSIS脚本组件中扁平文件Header与Detail合并的问题

你现在遇到的核心问题是按行类型分组后,没法把Header和Detail对应起来——毕竟没有关联ID,分开的两组数据自然没法合并。其实这类Header+Detail结构的扁平文件处理,核心思路是缓存Header数据,遇到Detail时直接合并输出,如果是一个Header对应多个Detail,就先缓存所有Detail再和Header一起输出。下面给你两种常见场景的具体实现:

场景1:一个Header对应一个Detail(一一对应)

这种情况是扁平文件里每一个Header行后面跟着一个Detail行,我们只需要把Header的字段暂存起来,读到Detail时就把两者合并成一条输出记录。

脚本实现步骤:

  1. 先在SSIS脚本组件的输出列里,添加所有需要的Header字段和Detail字段(比如HeaderID、HeaderName、DetailAmount、DetailDate等)。
  2. 打开脚本编辑器,声明类级别的变量来存储Header数据(这些变量会在整个脚本执行期间保留值):
// 类级变量,用于暂存Header字段
private string _headerID;
private string _headerName;
  1. 在CreateNewOutputRows方法里编写读取逻辑:
public override void CreateNewOutputRows()
{
    // 替换成你的扁平文件路径
    string flatFilePath = @"C:\Data\YourFlatFile.txt";
    
    using (StreamReader sr = new StreamReader(flatFilePath, Encoding.Default))
    {
        string line;
        while ((line = sr.ReadLine()) != null)
        {
            // 假设每行第一个字符是行类型标识:H=Header,D=Detail
            string recordType = line.Substring(0, 1).Trim();
            
            if (recordType == "H")
            {
                // 解析Header行,根据你的文件格式调整截取位置和长度
                _headerID = line.Substring(1, 8).Trim();
                _headerName = line.Substring(9, 20).Trim();
                // 其他Header字段同理解析
            }
            else if (recordType == "D")
            {
                // 解析Detail行
                string detailAmount = line.Substring(1, 10).Trim();
                string detailDate = line.Substring(11, 10).Trim();
                // 其他Detail字段同理解析
                
                // 创建输出行,合并Header和Detail数据
                Output0Buffer.AddRow();
                Output0Buffer.HeaderID = _headerID;
                Output0Buffer.HeaderName = _headerName;
                Output0Buffer.DetailAmount = decimal.Parse(detailAmount); // 注意类型转换
                Output0Buffer.DetailDate = DateTime.Parse(detailDate);
                // 映射所有输出列
            }
        }
    }
}

场景2:一个Header对应多个Detail(一对多,合并为单条记录)

如果是一个Header后面跟着多条Detail,需要把所有Detail的内容合并到一个字段里(比如用逗号分隔),再和Header一起输出。

脚本实现步骤:

  1. 在输出列里添加Header字段和一个用于存储合并后Detail的字段(比如MergedDetails,类型为字符串)。
  2. 声明类级变量:
private string _currentHeaderID;
private StringBuilder _detailBuilder;
  1. 在CreateNewOutputRows方法里编写逻辑:
public override void CreateNewOutputRows()
{
    string flatFilePath = @"C:\Data\YourFlatFile.txt";
    
    using (StreamReader sr = new StreamReader(flatFilePath))
    {
        string line;
        while ((line = sr.ReadLine()) != null)
        {
            string recordType = line.Substring(0, 1).Trim();
            
            if (recordType == "H")
            {
                // 如果之前有未输出的Header和Detail,先输出
                if (_detailBuilder != null && _detailBuilder.Length > 0)
                {
                    Output0Buffer.AddRow();
                    Output0Buffer.HeaderID = _currentHeaderID;
                    Output0Buffer.MergedDetails = _detailBuilder.ToString();
                    // 重置StringBuilder
                    _detailBuilder.Clear();
                }
                
                // 存储当前Header数据
                _currentHeaderID = line.Substring(1, 8).Trim();
                // 初始化StringBuilder用于缓存Detail
                _detailBuilder = new StringBuilder();
            }
            else if (recordType == "D")
            {
                // 解析Detail内容,这里假设取除了行类型外的所有内容
                string detailContent = line.Substring(1).Trim();
                // 追加到StringBuilder,用逗号分隔(可自定义分隔符)
                if (_detailBuilder.Length > 0)
                {
                    _detailBuilder.Append(", ");
                }
                _detailBuilder.Append(detailContent);
            }
        }
        
        // 处理最后一组Header和Detail,避免遗漏
        if (_detailBuilder != null && _detailBuilder.Length > 0)
        {
            Output0Buffer.AddRow();
            Output0Buffer.HeaderID = _currentHeaderID;
            Output0Buffer.MergedDetails = _detailBuilder.ToString();
        }
    }
}

关键注意事项

  • 字段解析要准确:一定要根据你的扁平文件实际格式调整Substring的起始位置和长度,避免截取错误。如果是分隔符文件,也可以用Split方法拆分字段。
  • 处理边缘情况:比如遇到没有对应Detail的Header,或者没有对应Header的Detail,可以添加判断逻辑,比如跳过这类行,或者输出到错误行里。
  • 编码问题:如果你的扁平文件有特殊编码(比如UTF-8、GB2312),一定要在StreamReader里指定对应的编码,避免乱码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:32:19