SSIS: 从平面文件源到SQL,避免重复行

3

我是一名有用的助手,可以为您翻译文本。

我有一个(有点大的)平面文件(csv)。我试图使用SSIS包将其导入到我的SQL Server表中。没有什么特别的,只是简单的导入。问题是,超过50%的行是重复的。

例如,数据:

Item Number    |    Item Name     |     Update Date
ITEM-01        | First Item       | 1-Jan-2013
ITEM-01        | First Item       | 5-Jan-2013
ITEM-24        | Another Item     | 12-Mar-2012
ITEM-24        | Another Item     | 13-Mar-2012
ITEM-24        | Another Item     | 14-Mar-2012

现在我需要使用这些数据创建我的主项目记录表,如您所见,由于更新日期的缘故,数据是重复的。保证文件始终按照项目编号进行排序。因此,我只需要检查如果下一个项目编号=上一个项目编号,则不导入此行
我在SSIS包中使用了排序和删除重复项,但实际上它正在尝试对所有行进行排序,这是无用的,因为行已经排序。此外,这将花费很长时间来排序太多行。
那么还有其他方法吗?
2个回答

5
有几种方法可以实现这个目的。
1. 聚合转换
Item NumberItem Name进行分组,然后对Update Date执行聚合操作。根据您上面提到的逻辑,应该使用最小值操作。为了使用Minimum操作,您需要将Update Date列转换为日期(无法在字符串上执行Minimum)。这种转换可以在Data Conversion Transformation中完成。以下是其核心内容:

enter image description here

2. 脚本组件转换
基本上,您可以实现上述逻辑:

如果下一个项目编号=上一个项目编号,则不导入此行

首先,您必须适当地配置脚本组件(以下步骤假定您没有重命名默认输入和输出名称):
  1. 选择Transformation作为脚本组件类型
  2. 在数据流中的Flat File Source之后添加脚本组件:
  3. enter image description here

  4. 双击脚本组件以打开Script Transformation Editor
  5. Input Columns下,选择所有列:
  6. enter image description here

  7. Inputs and Outputs下,选择Output 0,并将SynchronousInputID属性设置为None
  8. enter image description here

  9. 现在手动添加列到Output 0以匹配Input 0中的列(不要忘记设置数据类型):
  10. enter image description here

  11. 最后,编辑脚本。将会有一个名为Input0_ProcessInputRow的方法-按照下面的方式修改它,并添加一个名为previousItemNumber的私有字段:
    public override void Input0_ProcessInputRow(Input0Buffer Row)
    {
        if (!Row.ItemNumber.Equals(previousItemNumber))
        {
            Output0Buffer.AddRow();
            Output0Buffer.ItemName = Row.ItemName;
            Output0Buffer.ItemNumber = Row.ItemNumber;
            Output0Buffer.UpdateDate = Row.UpdateDate;
        }  

        previousItemNumber = Row.ItemNumber;
    }

    private string previousItemNumber = string.Empty;

感谢gannaway的回答,我提供的示例数据并不是实际数据。实际数据有太多列,因此第一种方法不适用。我将尝试使用第二种方法并发布更新。 - sallushan
考虑更进一步,你可以采用自定义脚本组件源码,仅将唯一的记录读入到管道中(上述脚本组件转换方法会将所有记录读入管道,然后再过滤它们)。这需要开发人员编写代码读取文件内容,因此需要更多的工作量。此外,我不确定它是否会提供多少性能优势(如果有的话)。但是,这仍然是另一个选项。 - gannaway
是的,我认为我必须使用自定义代码,无论是使用SSIS还是一些自定义的C#工具,因为文件中存在一些数据错误,这也导致了Flat File Source无法完全处理该文件。可能需要在导入过程之前清理文件。感谢gannaway的帮助。 - sallushan

0
如果性能对您很重要,我建议您将整个文本文件倒入SQL Server的临时表中,然后使用SELECT DISTINCT *来获取所需的值。

谢谢Eli,问题在于数据太大了,如果我要导入整个数据,这将需要时间,而且会显著增加数据库的大小。因此,这对我们来说不是一个好主意。 - sallushan
1
@sallushan 或许是一个临时数据库? - Eli Ekstein

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接