use*_*884 6 sql-server csv ssis etl flat-file
我有一个任务来加载格式异常的文本文件。该文件也包含不需要的数据。它包含两个连续的标头,每个标头的数据在备用行上指定。标题行从之后开始------。我需要同时读取标头及其对应的数据,并使用将其转储到某些Excel /表目标中。让我知道如何使用SSIS中的任何转换或脚本来解决此问题。不知道该如何使用脚本任务。
现在,我正在读取文件的一列,并使用派生的列手动尝试使用substring功能对其进行拆分。但这仅适用于一个标头,并且编码类型太硬。我需要一些动态方法来直接读取标题行和数据行。
输入文件:
A1234-012 I N F O R M A T I C S C O M P A N Y 08/23/17
PAGE 2 BATCH ABC PAYMENT DATE & DUE DATE EDIT PAGE 481
------------------------------------------------------------------------------------------------------------------------------------
SEO XRAT CLT LOAN OPENING PAYMENT MATURIUH LOAN NEXE ORIG-AMT OFF TO CATE CONTC MON NO.TO TOL NEL S CUP CO IND PAT
NOM CODE NOM NOMTER DATE DUO DATE DATE TIME PT # MONEY AQ LOAN NUMBER BLOCK PAYMENT U TYP GH OMG IND
1-3 4-6 7-13/90-102 14-19 20-25 26-31 32-34 35-37 38-46 47-48 49 50-51 52-61 62 63 64-72 73 4-5 76 77 8-80
------------------------------------------------------------------------------------------------------------------------------------
SEO XRAT CLT LOAN A/C A/C MIN MAX MAX PENDI LATE CCH L/F PARTLYS CUR L/F L/F L/F
NOM CODE NOM NOMTER CODE FACTOR MON MON ROAD DAYS MONE POT L/A L/F JAC INT VAD CD USED PI VAD DT
1-3 4-6 7-13/90-102 14 15 20-23 24-29 30-34 35-37 38-42 43 44 49 60 61-63 64-69
USED-ID:
------------------------------------------------------------------------------------------------------------------------------------
454542 070 567 2136547895 08-08-18 08-06-18 11-02-18 123 256 62,222 LK 5 55 5463218975 5 3 5,555.22 33 H55
025641 055 123 5144511352 B .55321 2.55 6531.22 H #AS
454542 070 567 2136547895 08-08-18 08-06-18 11-02-18 123 256 62,222 LK 5 55 5463218975 5 3 5,555.22 33 H55
025641 055 123 5144511352 B .55321 2.55 6531.22 H #AS
454542 070 567 2136547895 08-08-18 08-06-18 11-02-18 123 256 62,222 LK 5 55 5463218975 5 3 5,555.22 33 H55
025641 055 123 5144511352 B .55321 2.55 6531.22 H #AS
Run Code Online (Sandbox Code Playgroud)
预期输出应为:
文件1:
SEO XRAT CLT LOAN OPENING PAYMENT MATURIUH LOAN NEXE ORIG-AMT OFF TO CATE CONTC MON NO.TO TOL NEL S CUP CO IND PAT
NOM CODE NOM NOMTER DATE DUO DATE DATE TIME PT # MONEY AQ LOAN NUMBER BLOCK PAYMENT U TYP GH OMG IND
454542 070 567 2136547895 08-08-18 08-06-18 11-02-18 123 256 62,222 LK 5 55 5463218975 5 3 5,555.22 33 H55
454542 070 567 2136547895 08-08-18 08-06-18 11-02-18 123 256 62,222 LK 5 55 5463218975 5 3 5,555.22 33 H55
454542 070 567 2136547895 08-08-18 08-06-18 11-02-18 123 256 62,222 LK 5 55 5463218975 5 3 5,555.22 33 H55
Run Code Online (Sandbox Code Playgroud)
文件2:
SEO XRAT CLT LOAN A/C A/C MIN MAX MAX PENDI LATE CCH L/F PARTLYS CUR L/F L/F L/F
NOM CODE NOM NOMTER CODE FACTOR MON MON ROAD DAYS MONE POT L/A L/F JAC INT VAD CD USED PI VAD DT
025641 055 123 5144511352 B .55321 2.55 6531.22 H #AS
025641 055 123 5144511352 B .55321 2.55 6531.22 H #AS
025641 055 123 5144511352 B .55321 2.55 6531.22 H #AS
Run Code Online (Sandbox Code Playgroud)
要忽略前三行,您可以简单地将平面文件连接管理器配置为忽略它们,类似于:
1.配置连接管理器
此外,在平面文件连接管理器中,转到“高级”选项卡,删除除一列之外的所有列,并将其数据类型更改为DT_STR,将MaxLength更改为4000。
添加两个连接管理器,每个目标文件一个,其中您只能定义一列,最大长度为4000:
2.配置数据流任务
添加一个数据流任务,并在其中添加一个平面文件源。选择源文件连接管理器。
使用以下表达式添加条件拆分:
文件1
FINDSTRING([Column 0],"OPENING",1) > 1 || FINDSTRING([Column 0],"DATE",1) > 1 || TOKENCOUNT([Column 0]," ") == 19
Run Code Online (Sandbox Code Playgroud)
文件2
FINDSTRING([Column 0],"A/C",1) > 1 || FINDSTRING([Column 0],"FACTOR",1) > 1 || TOKENCOUNT([Column 0]," ") == 10
Run Code Online (Sandbox Code Playgroud)
上面的表达式是根据您在问题中提到的预期输出创建的,我很累在每个标头中搜索唯一的关键字,并根据出现的空间数拆分了数据行。
最后,将每个输出映射到目标平面文件组件:
执行结果显示在以下屏幕截图中:
要删除重复项,您必须参考以下链接:
如果只需要删除重复的标题,则可以分两个步骤进行:
另外,由于column值不包含空格,您可以使用正则表达式用单个Tab替换空格以使文件一致。
脚本组件
在脚本组件中,添加类型为DT_BOOL的输出列,并为其命名,outFlag并添加outColumn0类型DT_STR和长度等于或等于输出的输出列,4000然后选择Column0作为输入列。
然后在脚本编辑器(C#)中编写以下脚本:
首先确保您添加RegularExpressions命名空间
using System.Text.RegularExpressions;
Run Code Online (Sandbox Code Playgroud)
脚本代码
int SEOCount = 0;
int NOMCount = 0;
Regex regex = new Regex("[ ]{2,}", RegexOptions.None);
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
if (Row.Column0.Trim().StartsWith("SEO"))
{
if (SEOCount == 0)
{
SEOCount++;
Row.outFlag = true;
}
else
{
Row.outFlag = false;
}
}
else if (Row.Column0.Trim().StartsWith("NOM"))
{
if (NOMCount == 0)
{
NOMCount++;
Row.outFlag = true;
}
else
{
Row.outFlag = false;
}
}
else if (Row.Column0.Trim().StartsWith("PAGE"))
{
Row.outFlag = false;
}
else
{
Row.outFlag = true;
}
Row.outColumn0 = regex.Replace(Row.Column0.TrimStart(), "\t");
}
Run Code Online (Sandbox Code Playgroud)
有条件拆分
在每个脚本组件之后添加条件拆分,并使用以下表达式过滤重复的标头:
[outFlag] == True
Run Code Online (Sandbox Code Playgroud)
并将条件拆分连接到目标。确保映射outColumn0到目标列。
套餐链接