SSIS做了两件与处理平面文件有关的事情,这些事情特别令人沮丧,似乎应该有办法绕过它们,但我无法弄明白.如果您定义一个包含10列的平面文件,使用CRLF作为行结束标记分隔的制表符,这将完美适用于每行中恰好有10列的文件.这两个痛苦的场景是:
如果有人在任何地方提供了第11列的文件,那么如果SSIS完全忽略它,那将是很好的,因为你还没有定义它.它应该只读取你定义的10列,然后跳到行标记的末尾,但是相反的是将任何附加数据与第10列中的数据连接起来,然后将所有数据连接到第10列.真有点没用.我意识到这种情况发生是因为第10列的分隔符不是像所有其他分区一样的选项卡,而是CRLF,所以它只是将所有内容都抓到了CRLF,因此无需更换额外的选项卡.在我看来,这并不聪明.
如果有人提供的文件只有9列,那就更糟了.它会暂时忽略它意外发现的CRLF,并用下一行开头的列填充任何缺少的列!不聪明在这里是轻描淡写.谁会想要发生这种情况?此时文件的其余部分是垃圾.
无论出于何种原因,文件宽度的变化似乎都是不合理的(当然,只有行的末尾的变化才能被处理(x更少或更多的列),但看起来这样处理不好,除非我我错过了什么.
到目前为止,我们唯一的解决方案是将一行加载为一个巨型列(column0),然后使用脚本任务使用它找到的许多分隔符动态分割它.这很有效,除了它将行宽限制为4000个字符(一个unicode列的最大宽度).如果您需要导入更宽的行(例如,使用多个4000宽的列进行文本导入),则需要如上所述定义多个列,但是您需要每行需要严格的列数.
有没有解决这些限制的方法?
小智 12
格伦,我觉得你的痛苦:) SSIS不能使列动态,因为它需要存储每列的元数据,因为我们正在处理可以包含任何类型的数据的平面文件,它不能假设CRLF在'列那不是最后一列'中,确实是它应该读取的数据行的末尾.
与SQL2000中的DTS不同,您无法在运行时更改SSIS包的属性.
您可以做的是创建一个父包,它读取平面文件(脚本任务),只读取平面文件的第一行以获取列数和列名.此信息可以存储在变量中.
然后,父包以编程方式加载子包(脚本任务),并更新子包的源连接的元数据.您可以在此处添加/删除列以匹配平面文件.2.设置列的列分隔符,最后一列必须是CRLF - 与ROW分隔符匹配3.重新初始化Dataflow任务中Source Compoenent的元数据(ComponentMetadata.ReinitializeMetadata())(以识别最近的更改)源连接).4.保存子ssis包.
以编程方式修改程序包的详细信息仅供参考.
然后,您的父包只执行子包(执行包任务),它将使用您的新映射执行.