我需要使用SSIS将几千个txt文件放到SQL Server 2012实例中。
问题是某些txt文件的前两行中有控制校验和,而其他一些则没有。
如果文件有校验和,则其第一行以“HEADER”开头 - 在这种情况下,我必须跳过前两行,然后从第3行读取列标题并从第4行开始加载数据。
如果文件没有校验和,则第1行中将存在列名,数据将从第2行开始。
现在,我的问题是:处理这种情况的侵入性最小的方法是什么?我很懒,所以我正在寻找最小效果的最小努力。
到目前为止我的想法:
使用C#脚本编写组件检测校验和的存在,并构建两个单独的流,每个文件类型一个。缺点:两个几乎相同的流程(我不是冗余的忠实粉丝)
首先使用PowerShell在运行SSIS流之前从文件中删除校验和。缺点:需要重写大量文件(性能命中)
在StackOverflow上询问。缺点:StackOverflow社区可以看作具有讽刺意味。
任何提示?
答案 0 :(得分:2)
这是一种方法。
Header Rows to Skip
保留为0,对于具有校验和行的Flat File Connection Manager,将其设置为跳过前2行,如下所示。
DelayValidation
属性设置为true
。HasCheckSumRows
HasCheckSumRows
标记设置为true
进行拆分,并创建2个输出,1用于带有校验和行的文件,其他用于没有文件。connectionstring
。 希望这是有道理的。
答案 1 :(得分:0)
我会在评论中写下这个,但是你知道我在使用多年后很难做出贡献。无论如何,只有拥有Checksum行条件的冗余数据流的选项1可能是最直接的方法,并且看到您的数据集列有限可能是创建和维护最快的。对于这种方法,您可以放入Foreach循环容器,将其设置为枚举文件。添加一个变量来测试校验和是否存在。添加c#脚本任务以测试校验和并填充变量。然后添加2个数据流任务1来处理一种格式,第二种添加另一种格式。它只是4个组件的重复(FileConnection,Dataflow,source,destination)。然后对于优先约束编辑器(双击绿色箭头)更改为通过表达式中的表达式和约束进行评估,只需选择您的变量或!变量(相反),具体取决于正在馈送的数据流。这假设你没有首先将同一数据流任务中的所有2000多个文件与工会等组合在一起。在@Shiva答案中肯定会有很多交叉,但我不认为需要进行条件拆分如果你要去一个临时表,那就结合了。
如果您真的不想要数据流任务的冗余等,请注意另一个注意事项。在运行SSIS包之前,无需执行powershell脚本。您可以创建一个c#脚本以在包中正确执行。例如,我遇到的问题是,我必须导入的数据源的行结尾不一致。所以我有一个c#脚本来规范化在我的数据流任务之前保存文件的行结尾。您可以在ssis包中将文件规范化为一个结构,但是当您指出文件已经被加载到内存/处理时,它将需要额外的系统资源。
@xpil,15个原始问题中没有不同的类型。我可能会做两件事中的一件。首先实现#2的想法,但在SSIS脚本中执行。所以我会通过system.file.io操作删除不需要的行。然后我会构建所有不同的类型并在脚本中设置一个变量,告诉你它是哪种类型或通过不同的dfts失败。或者我实际上只是编写整个操作的脚本,我可能会或者可能不会使用SSIS但是我只需要一个system.file.io来加载文件检测存在和类型然后只需使用SQLBulkCopy将它放入表中然后而不是创建DFT在设置上会花费更少的时间。虽然如果文件大到几百MB,你可能仍然想要去DFT路线。以下是我编写的SSIS脚本任务的一些片段,当然您需要根据自己的需要进行更改。
如果要去修复文件和DFT路线。
string contents = File.ReadAllText(_WFRFullPath);
contents = Regex.Replace(contents, @"\r\n?|\n", crlf);
File.WriteAllText(_SSISWorkspaceFullPath, contents);
通过正则表达式写入文件将文件内容修复回新位置。
如果通过脚本路由加载,那么您只需要将其读取为数据表,然后可能通过列名称或数据类型将其读取为测试格式。然后加载它。
SqlConnection sqlConnection = new SqlConnection(sqlConnectionString);
sqlConnection.Open();
SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConnection);
bulkCopy.DestinationTableName = _stagingTableName;
foreach (DataColumn col in _jobRecDT.Columns)
{
//System.Windows.Forms.MessageBox.Show(col.ColumnName);
bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);
}
bulkCopy.WriteToServer(_jobRecDT);
sqlConnection.Close();
注意我手头没有代码,但是如果你有大文件,你可以实际实现一个流阅读器并将文件大块化并批量复制。