0

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

//No batch level error
00000BH
00123NRNormalRecordData
00000NRNormalRecordDataNoError
00000BT

看起来像:

╔═══════════╦══════════════════╗
║   Error   ║   Record Data    ║
╠═══════════╬══════════════════╣
║       123 ║ NormalRecordData ║
╚═══════════╩══════════════════╝

和:

//Batch level error
05555BH
00000NRNormalRecordData
00000NRNormalRecordData
00000BT

看起来像:

╔═══════╦═════════════════════════╗
║ Error ║       Record Data       ║
╠═══════╬═════════════════════════╣
║  5555 ║ NormalRecordData        ║
║       ║                         ║
║  5555 ║ NormalRecordData        ║
╚═══════╩═════════════════════════╝

我的问题是多批次现在搞砸了(曾经只有一批)。现在我想做如下的事情

//Multi batch
00000BH
00123NRNormalRecordError
00000NRNormalRecord
00000BT
00000BH
00000SRSecondaryRecordType //want to ignore batches with no NR normal records
00000BT
05555BH
00000NRNormalRecord
00000NRNormalRecord
00000BT

由于将批次级错误保存到变量中并在我写出记录时检查它是否为空,因此该报告错误地如下所示:

╔═══════╦═════════════════════╗
║ Error ║    Record Data      ║
╠═══════╬═════════════════════╣
║  5555 ║ NormalRecordError   ║
║  5555 ║ SecondaryRecordType ║
║  5555 ║ NormalRecord        ║
║  5555 ║ NormalRecord        ║
║  5555 ║ NormalRecord        ║
╚═══════╩═════════════════════╝

当我希望它看起来像:

╔═══════╦═══════════════════╗
║ Error ║    Record Data    ║
╠═══════╬═══════════════════╣
║  123  ║ NormalRecordError ║
║  5555 ║ NormalRecord      ║
║  5555 ║ NormalRecord      ║
╚═══════╩═══════════════════╝

这是因为逻辑看起来有点像:

  • store batch level error 获取所有有错误的正常记录,除非
  • 批处理级别错误> 0 然后让它们全部用批处理写入所有行
  • 级别错误,如果有一个或只写正常行该错误(这种情况将按预期工作,因为未填充批处理级别变量)

我的第一个想法是有条件的分裂。但是,这只会让我在行级别做一个条件,因为我需要之前出现的行的上下文。

你会如何解决这个问题?

4

1 回答 1

1

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

  1. 我使用上面的数据制作了一个带有列名数据的单列平面文件
  2. 添加脚本组件作为转换
  3. 检查数据作为输入列
  4. 添加名为 RecordOutput 的新输出
  5. 将列添加到输出:error as int,RecordData as 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);
        }
    }

}

这是组件的外观: 在此处输入图像描述

结果如下: 在此处输入图像描述

于 2014-10-29T15:01:07.063 回答