如何跳过ssis中的动态标题行

时间:2019-09-21 05:57:15

标签: sql-server csv ssis etl flat-file

嗨,我对SSIS有一个疑问, 我想使用SSIS包将多个csv文件加载到SQL Server表中。 在加载时间时,我们需要考虑病房标头中的数据。

源路径具有3个带有固定标题列且具有数据的csv文件 但每个文件在标头和 一个文件描述来自2row,标题行从第4行开始,并包含数据。 另一个文件描述来自第1行和第9行,在病房中具有带数据的标题,另一个文件来自第5行,文件头来自第7行。列标题固定在所有csv文件中

文件位置:

  1. C:\ test \ a.csv
  2. C:\ test \ b.csv
  3. C:\ test \ c.csv

a.csv文件数据如下:

here descritpion and dates comes 2and 3 row.actual data start from 4th row onwards
descritiion:empinfromationforhydlocation
creadeddate:2018-04-20

id |name|loc
1  |a   |hyd

b.csv文件数据如下:

here descritpion and dates comes 1and 2 row.actual data start from 9th row onwards
descritiion:empinfromationforhydlocation
creadeddate:2018-04-21

id |name|loc
10  |b   |chen

c.csv file data like below :

here descritpion and comes 5 and 6 row.actual data start from 9th row onwards
descritiion:empinfromationforhydlocation
creadeddate:2018-04-21

id |name|loc
20  |c   |bang

基于上述3个文件,我想将数据加载到目标sql服务器表emp中:

id  | Name |Sal
1   |a     |hyd
2   |b     |chen
3   |c     |bang

在这里,我在包装方面尝试过以下方式:

  1. 创建变量:
    • 文件位置路径:C:\ test \
    • 文件名:C:\ test \ a.csv
  2. 拖放for-each循环容器:
    • 为每个文件枚举器选择枚举器类型
    • 目录:c:\ test
    • 变量映射:文件名对其进行配置。
    • 文件类型:* .csv
    • 检索文件名:文件名和扩展名
  3. 在for-each循环容器中,我拖放数据流任务 并创建平面文件连接,此处使用配置文件之一,跳过标头行为1,并使用数据转换所需的列并配置到OLE DB目标表,并创建用于平面文件连接的动态连接表达式以动态传递文件名。

执行软件包后,由于描述和日期信息,第二个文件失败:

  • 描述和日期不是固定地出现在第二天的固定行
  • 说明和日期将带有不同的行

是否有可能动态找到要跳过的行数,并且该计数将在标头行跳过中传递。在SSIS中是可能的。

请告诉我如何在SSIS中完成此任务

3 个答案:

答案 0 :(得分:1)

解决方法

  1. 在“平面文件”连接管理器中,取消选中“从第一行读取标题”选项,然后转到“高级”选项卡并手动定义列元数据(列名,长度...)
  2. 在“数据流任务”中,添加脚本组件
  3. 在“脚本组件编辑器”中,转到“输入和输出”选项卡,然后添加一个布尔类型的“输出”列
  4. 在脚本编辑器中,请继续检查第一列值是否等于列标题,如果不满足此条件,请始终在列值等于列时将输出列值设置为false标题,然后将所有剩余行的输出列值设置为True
  5. 在脚本组件旁边,根据生成的列值添加条件拆分以过滤行(必须忽略具有False值的行)

答案 1 :(得分:0)

如果您一直需要跳过的行数,请尝试在utube上找到以下视频:从SSIS包的平面文件中删除前N行
如果您仍然需要找到该金额,但又不知道尝试将无用的行的金额写入变量,然后将该值粘贴到包中以进行处理,则不知道。

答案 2 :(得分:0)

为同一文件创建一个具有单列的新文件连接。

使用转换脚本组件添加数据流任务。

将读写变量附加到脚本组件作为索引(示例代码中的skiprows)并检查流程输入行中每行的第一个字符。

bool checkRow;
int rowCount;
public override void PreExecute()
{
    base.PreExecute();
    checkRow = true;
    rowCount = 0;
}
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
    if (checkRow)
    {
        rowCount++;
        if (Row.Data.StartsWith("id |"))
            checkRow = false;
    }
}
public override void PostExecute()
{
    base.PostExecute();
    Variables.skiprows = rowCount;//set script variable
}

然后,您只需在原始平面文件连接的表达式“HeaderRowsToSkip”中设置变量即可。

如果文件将非常大,您可以在找到第一行时强制脚本失败(例如零分割)。添加错误事件并将系统变量“Propagate”设置为false(@[System::Propagate]=false)。