【问题标题】:SSIS: Flat File Source to SQL without Duplicate RowsSSIS:没有重复行的 SQL 平面文件源
【发布时间】:2014-01-16 08:59:34
【问题描述】:

我有一个(有点大)平面文件 (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 包中使用了带有删除重复项的排序,但它实际上是在尝试对所有无用的行进行排序,因为行已经排序。另外,对太多行进行排序需要很长时间。

那么还有其他方法吗?

【问题讨论】:

    标签: ssis


    【解决方案1】:

    您可以采取几种方法来做到这一点。

    1。聚合转换

    Item NumberItem Name 分组,然后对Update Date 执行聚合操作。根据您上面提到的逻辑,Minimum 操作应该可以工作。为了使用 Minimum 操作,您需要将 Update Date 列转换为日期(不能对字符串执行 Minimum)。该转换可以在数据转换转换中完成。以下是它的外观:

    2。脚本组件转换

    基本上,你可以实现你上面提到的逻辑:

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

    首先,您必须适当配置脚本组件(以下步骤假设您不重命名默认输入和输出名称):

    1. 选择Transformation作为脚本组件类型
    2. 在数据流中的平面文件源之后添加脚本组件:

    3. 双击脚本组件打开脚本转换编辑器
    4. 输入列下,选择所有列:

    5. Inputs and Outputs下,选择Output 0,并将SynchronousInputID属性设置为None

    6. 现在手动将列添加到 Output 0 以匹配 Input 0 中的列(不要忘记设置数据类型):

    7. 最后,编辑脚本。将有一个名为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 的回答,我提供的示例数据不是实际数据。实际数据的列太多,因此第一种方法不适用。我将尝试使用第二种方法并发布更新。
    • 再想一想,你可以更进一步,只做一个自定义的脚本组件源,只将唯一的记录读入管道(上面的脚本组件转换方法将所有记录读入管道和然后过滤掉它们)。由于开发人员负责编写代码以读取文件的内容,因此需要做更多的工作。另外,我不确定它会提供多少性能优势(如果有的话)。但是,无论如何,这是另一种选择。
    • 是的,我想我必须使用自定义代码,使用 SSIS 或一些自定义 C# 工具,因为文件也有一些数据错误,这会阻止文件(完全)使用平面文件资源。可能我需要先清理文件,然后才能将其用于导入过程。感谢 gannaway 的帮助。
    【解决方案2】:

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

    【讨论】:

    • 谢谢 Eli,问题是数据太大,如果我要导入整个数据,这将需要时间,而且会显着增加数据库大小。所以这对我们来说不是一个好主意。
    • @sallushan 也许是一个临时数据库?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-19
    • 2018-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多