SSIS处理平面文件中标头和尾部之间的记录

SSIS处理平面文件中标头和尾部之间的记录,ssis,batch-processing,flat-file,ssis-2012,Ssis,Batch Processing,Flat File,Ssis 2012,我有一个SSIS包,它使用条件拆分来获取以行分隔的平面文件中的任何批处理头或尾部,获取第一行,并从中获取错误代码。如果错误代码>0,我会将批标题和尾部之间的所有正常记录写入带有该错误代码的报告。否则,我只写出带有错误代码的正常记录。下面是该示例的内容: //No batch level error 00000BH 00123NRNormalRecordData 00000NRNormalRecordDataNoError 00000BT 这看起来像: ╔═══════════╦════════

我有一个SSIS包,它使用条件拆分来获取以行分隔的平面文件中的任何批处理头或尾部,获取第一行,并从中获取错误代码。如果错误代码>0,我会将批标题和尾部之间的所有正常记录写入带有该错误代码的报告。否则,我只写出带有错误代码的正常记录。下面是该示例的内容:

//No batch level error
00000BH
00123NRNormalRecordData
00000NRNormalRecordDataNoError
00000BT
这看起来像:

╔═══════════╦══════════════════╗
║   Error   ║   Record Data    ║
╠═══════════╬══════════════════╣
║       123 ║ NormalRecordData ║
╚═══════════╩══════════════════╝
╔═══════╦═════════════════════════╗
║ Error ║       Record Data       ║
╠═══════╬═════════════════════════╣
║  5555 ║ NormalRecordData        ║
║       ║                         ║
║  5555 ║ NormalRecordData        ║
╚═══════╩═════════════════════════╝
╔═══════╦═════════════════════╗
║ Error ║    Record Data      ║
╠═══════╬═════════════════════╣
║  5555 ║ NormalRecordError   ║
║  5555 ║ SecondaryRecordType ║
║  5555 ║ NormalRecord        ║
║  5555 ║ NormalRecord        ║
║  5555 ║ NormalRecord        ║
╚═══════╩═════════════════════╝
╔═══════╦═══════════════════╗
║ Error ║    Record Data    ║
╠═══════╬═══════════════════╣
║  123  ║ NormalRecordError ║
║  5555 ║ NormalRecord      ║
║  5555 ║ NormalRecord      ║
╚═══════╩═══════════════════╝
以及:

这看起来像:

╔═══════════╦══════════════════╗
║   Error   ║   Record Data    ║
╠═══════════╬══════════════════╣
║       123 ║ NormalRecordData ║
╚═══════════╩══════════════════╝
╔═══════╦═════════════════════════╗
║ Error ║       Record Data       ║
╠═══════╬═════════════════════════╣
║  5555 ║ NormalRecordData        ║
║       ║                         ║
║  5555 ║ NormalRecordData        ║
╚═══════╩═════════════════════════╝
╔═══════╦═════════════════════╗
║ Error ║    Record Data      ║
╠═══════╬═════════════════════╣
║  5555 ║ NormalRecordError   ║
║  5555 ║ SecondaryRecordType ║
║  5555 ║ NormalRecord        ║
║  5555 ║ NormalRecord        ║
║  5555 ║ NormalRecord        ║
╚═══════╩═════════════════════╝
╔═══════╦═══════════════════╗
║ Error ║    Record Data    ║
╠═══════╬═══════════════════╣
║  123  ║ NormalRecordError ║
║  5555 ║ NormalRecord      ║
║  5555 ║ NormalRecord      ║
╚═══════╩═══════════════════╝
我的问题是有多个批次,现在这个问题搞砸了(过去只有一个批次)。现在我想做如下的事情

//Multi batch
00000BH
00123NRNormalRecordError
00000NRNormalRecord
00000BT
00000BH
00000SRSecondaryRecordType //want to ignore batches with no NR normal records
00000BT
05555BH
00000NRNormalRecord
00000NRNormalRecord
00000BT
由于将批处理级别错误保存到变量中,并在我写出记录时检查它是否为null,因此此报告将错误地显示为:

╔═══════════╦══════════════════╗
║   Error   ║   Record Data    ║
╠═══════════╬══════════════════╣
║       123 ║ NormalRecordData ║
╚═══════════╩══════════════════╝
╔═══════╦═════════════════════════╗
║ Error ║       Record Data       ║
╠═══════╬═════════════════════════╣
║  5555 ║ NormalRecordData        ║
║       ║                         ║
║  5555 ║ NormalRecordData        ║
╚═══════╩═════════════════════════╝
╔═══════╦═════════════════════╗
║ Error ║    Record Data      ║
╠═══════╬═════════════════════╣
║  5555 ║ NormalRecordError   ║
║  5555 ║ SecondaryRecordType ║
║  5555 ║ NormalRecord        ║
║  5555 ║ NormalRecord        ║
║  5555 ║ NormalRecord        ║
╚═══════╩═════════════════════╝
╔═══════╦═══════════════════╗
║ Error ║    Record Data    ║
╠═══════╬═══════════════════╣
║  123  ║ NormalRecordError ║
║  5555 ║ NormalRecord      ║
║  5555 ║ NormalRecord      ║
╚═══════╩═══════════════════╝
当我希望它看起来像:

╔═══════════╦══════════════════╗
║   Error   ║   Record Data    ║
╠═══════════╬══════════════════╣
║       123 ║ NormalRecordData ║
╚═══════════╩══════════════════╝
╔═══════╦═════════════════════════╗
║ Error ║       Record Data       ║
╠═══════╬═════════════════════════╣
║  5555 ║ NormalRecordData        ║
║       ║                         ║
║  5555 ║ NormalRecordData        ║
╚═══════╩═════════════════════════╝
╔═══════╦═════════════════════╗
║ Error ║    Record Data      ║
╠═══════╬═════════════════════╣
║  5555 ║ NormalRecordError   ║
║  5555 ║ SecondaryRecordType ║
║  5555 ║ NormalRecord        ║
║  5555 ║ NormalRecord        ║
║  5555 ║ NormalRecord        ║
╚═══════╩═════════════════════╝
╔═══════╦═══════════════════╗
║ Error ║    Record Data    ║
╠═══════╬═══════════════════╣
║  123  ║ NormalRecordError ║
║  5555 ║ NormalRecord      ║
║  5555 ║ NormalRecord      ║
╚═══════╩═══════════════════╝
这是因为逻辑看起来有点像:

  • 存储批处理级别错误获取包含错误的所有正常记录,除非
  • 批处理级别错误>0,然后让它们全部使用批处理写入所有行
  • 如果有一行或只写正常行发生错误,则为级别错误 (本例将按预期工作,因为批处理级别变量 (未填充)
我的第一个想法是有条件的分裂。然而,这只允许我在行级别执行一个条件,因为我需要前面的行的上下文


如何解决这个问题?

您可以使用脚本组件转换来解析列,并根据您的条件添加行。标头错误可以存储在在Input0\u ProcessInputRow方法之外声明的变量中。以下是我使用的步骤:

  • 我使用上面的数据创建了一个包含列名数据的单列平面文件
  • 添加脚本组件作为转换
  • 将数据检查为输入列
  • 添加名为RecordOutput的新输出
  • 将列添加到输出:错误为int,记录数据为string
  • 守则:

    using System;
    using System.Data;
    using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
    using Microsoft.SqlServer.Dts.Runtime.Wrapper;
    
    [Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
    public class ScriptMain : UserComponent
    {
    
        int error;
    
        public override void Input0_ProcessInputRow(Input0Buffer Row)
        {
            //gets the row type
    
            string rowType = Row.Data.Substring(5, 2);
    
            //only sets the error variable if it is a header record
            if (rowType == "BH")
            {
                error = Convert.ToInt32(Row.Data.Substring(0, 5));
            }
    
            //Only adds a record for NR rows
            if (rowType == "NR" && (error > 0 || Convert.ToInt32(Row.Data.Substring(0, 5)) > 0))
            {
                RecordOutputBuffer.AddRow();
                if (error > 0)
                {
                    RecordOutputBuffer.Error = error;
                }
                else
                {
                    RecordOutputBuffer.Error = Convert.ToInt32(Row.Data.Substring(0, 5));
                }
                RecordOutputBuffer.RecordData = Row.Data.Substring(7, Row.Data.Length - 7);
            }
        }
    
    }
    
    以下是组件的外观:

    结果如下: