SSIS任务不一致的列数导入?
问题。
我经常收到来自不同供应商的饲料文件。 虽然列名是一致的,但是当一些供应商发送文本文件时,问题就出现了,那里的文档文件中有更多或更less的列。
而且这些文件的安排是不一致的。
除了由Cosy Roc提供的dynamic数据stream任务之外,还有另一种方法可以导入这些文件。 我不是一个C#大师,但我被驱动使用“脚本任务”控制stream或“脚本组件”数据stream任务。
任何build议,样品或方向将非常感激。
http://www.cozyroc.com/ssis/data-flow-task
一些论坛
http://www.sqlservercentral.com/Forums/Topic525799-148-1.aspx#bm526400
http://www.bidn.com/forums/microsoft-business-intelligence/integration-services/26/dynamic-data-flow
我的头顶上,我有一个50%的解决scheme。
问题
SSIS 真的关心元数据,所以它的变化往往会导致exception。 从这个意义上说,DTS更为宽容。 对于一致的元数据的强烈需求使得使用平面文件源变得麻烦。
基于查询的scheme
如果问题是组件,我们不要使用它。 我喜欢这种方法,在概念上,就像查询表一样 – 列的顺序并不重要,额外列的存在也不重要。
variables
我创build了3个variables,所有types的string:CurrentFileName,InputFolder和Query。
- InputFolder硬连线到源文件夹。 在我的例子中,它是
C:\ssisdata\Kipreal
- CurrentFileName是文件的名称。 在devise期间,它是
input5columns.csv
但在运行时会改变。 - 查询是一个expression式
"SELECT col1, col2, col3, col4, col5 FROM " + @[User::CurrentFilename]
连接pipe理器
使用JET OLEDB驱动程序build立到input文件的连接。 按照链接文章中的描述创build后,我将其重命名为FileOLEDB,并在"Data Source=" + @[User::InputFolder] + ";Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=\"text;HDR=Yes;FMT=CSVDelimited;\";"
的ConnectionManager上设置expression式"Data Source=" + @[User::InputFolder] + ";Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=\"text;HDR=Yes;FMT=CSVDelimited;\";"
控制stream程
我的控制stream看起来像嵌套在Foreach文件枚举器中的数据stream任务
Foreach文件枚举器
我的Foreach文件枚举器被configuration为对文件进行操作。 我在@[User::InputFolder]
的目录上放置了一个expression式。注意,在这一点上,如果该文件夹的值需要更改,它将在Connection Manager和文件枚举器中正确更新。 在“检索文件名”中,而不是默认的“完全限定”,select“名称和扩展名”
在variables映射选项卡中,将值分配给我们的@[User::CurrentFileName]
variables
此时,循环的每次迭代都会改变@[User::Query
来反映当前的文件名。
数据stream
这实际上是最简单的一块。 使用一个OLE DB源并按照指示连线。
使用FileOLEDB连接pipe理器并将数据访问模式更改为“来自variables的SQL命令”。 在那里使用@[User::Query]
variables,点击OK,你就可以开始工作了。
示例数据
我创build了两个示例文件input5columns.csv和input7columns.csv 5的所有列都在7,但7有不同的顺序(col2是顺序位置2和6)。 我否定了7中的所有值,以便清楚地知道正在操作哪个文件。
col1,col3,col2,col5,col4 1,3,2,5,4 1111,3333,2222,5555,4444 11,33,22,55,44 111,333,222,555,444
和
col1,col3,col7,col5,col4,col6,col2 -1111,-3333,-7777,-5555,-4444,-6666,-2222 -111,-333,-777,-555,-444,-666,-222 -1,-3,-7,-5,-4,-6,-2 -11,-33,-77,-55,-44,-666,-222
在这两个屏幕截图中运行程序包
less了什么东西
我不知道一种方法来告诉基于查询的方法,如果一个列不存在,那就可以了。 如果有一个唯一的键,我想你可以定义你的查询只有那些必须在那里的列,然后对这个文件进行查找,试图获得那些应该在那里的列,而不是查找失败,不存在。 相当kludgey虽然。
我们的scheme 我们使用父子包。 在父pacakge中,我们将各个客户端文件转换为标准格式文件,然后调用子包来使用我们创build的文件处理标准导入。 这只有在客户端发送的内容一致的情况下才有效,如果他们尝试从他们同意发送给我们的内容中更改其格式,我们将返回该文件。