Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SSIS:SQL的平面文件源,无重复行_Ssis - Fatal编程技术网

SSIS:SQL的平面文件源,无重复行

SSIS:SQL的平面文件源,无重复行,ssis,Ssis,我有一个(有点大)平面文件(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

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


那么还有其他方法吗?

有几种方法可以做到这一点

1.聚合变换 按
项目编号
项目名称
分组,然后在
更新日期
执行聚合操作。根据您上面提到的逻辑,最小值操作应该可以工作。要使用最小值操作,需要将
更新日期
列转换为日期(不能对字符串执行最小值)。该转换可以在数据转换中完成。下面是这种情况的本质:

2.脚本组件转换 基本上,您可以实现上面提到的逻辑:

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

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

  • 选择转换作为脚本组件类型
  • 在数据流中的平面文件源之后添加脚本组件:

  • 双击脚本组件以打开脚本转换编辑器
  • 在输入列下,选择所有列:

  • 在输入和输出下,选择输出0,并将同步输入属性设置为无

  • 现在手动将列添加到输出0,以匹配输入0中的列(不要忘记设置数据类型):

  • 最后,编辑脚本。将有一个名为
    Input0\u ProcessInputRow
    的方法-按如下所示对其进行修改,并添加一个名为
    previousItemNumber
    的私有字段,如下所示:
  • public override void Input0\u ProcessInputRow(Input0Buffer行)
    {
    如果(!Row.ItemNumber.Equals(previousItemNumber))
    {
    Output0Buffer.AddRow();
    Output0Buffer.ItemName=行.ItemName;
    Output0Buffer.ItemNumber=行.ItemNumber;
    Output0Buffer.UpdateDate=行.UpdateDate;
    }  
    previousItemNumber=行.ItemNumber;
    }
    私有字符串previousItemNumber=string.Empty;
    
    如果性能对您来说很重要,我建议您将整个文本文件转储到SQL Server上的临时表中,然后使用
    选择DISTINCT*
    来获得所需的值。

    感谢gannaway的回答,我提供的示例数据不是实际数据。实际数据列太多,因此第一种方法不适用。我将尝试使用第二种方法并发布更新。考虑到这一点,您可以更进一步,只需执行自定义脚本组件源,并仅将唯一记录读取到管道中(上面的脚本组件转换方法将所有记录读取到管道中,然后将其过滤掉)。这将是一个多一点的工作,因为开发人员负责编写代码来读取文件的内容。此外,我不确定它能提供多少性能优势(如果有的话)。但是,不管怎样,这是另一种选择。是的,我认为我必须使用自定义代码,无论是使用SSI还是一些自定义C#工具,因为文件也有一些数据错误,这使得文件无法(完全)使用平面文件源。可能我需要先清理文件,然后才能将其交给导入过程。谢谢gannaway的帮助。谢谢Eli,问题是数据太大了,如果我要导入整个数据,这将需要时间,而且会大大增加数据库的大小。所以这对我们来说不是个好主意。@sallushan也许是一个临时的db?