在SSIS 2012的OLE DB源中使用动态SQL
我有一个存储过程作为SQL命令文本,它正在传递一个包含表名的参数。 proc然后从该表中返回数据。我无法直接将该表作为OLE DB源调用,因为某些业务逻辑需要发生在proc中的结果集中。在SQL 2008中,这工作得很好。在升级后的2012包中,我得到“元数据无法确定,因为...包含动态SQL,请考虑使用WITH RESULT SETS子句明确描述结果集。”在SSIS 2012的OLE DB源中使用动态SQL
问题是我无法在proc中定义字段名称,因为作为参数传递的表名可能是不同的值,并且每次生成的字段都可能不同。任何人遇到这个问题或有任何想法?我用动态SQL使用“dm_exec_describe_first_result_set”,包含WITH RESULT SETS的临时表和CTE尝试了各种各样的事情,但它在SSIS 2012中不起作用,同样的错误。上下文是很多动态SQL方法的问题。
这是我想最近的事,没有运气:
DECLARE @sql VARCHAR(MAX)
SET @sql = 'SELECT * FROM ' + @dataTableName
DECLARE @listStr VARCHAR(MAX)
SELECT @listStr = COALESCE(@listStr +',','') + [name] + ' ' + system_type_name FROM sys.dm_exec_describe_first_result_set(@sql, NULL, 1)
exec('exec(''SELECT * FROM myDataTable'') WITH RESULT SETS ((' + @listStr + '))')
那么请问出于好心,明白为什么上帝的绿色地球您使用的SSIS数据流任务来处理这样的动力源数据?
你正在运行陷入困境的原因是因为你的委曲的SSIS数据流任务的每一个宗旨:
- 提取与可静态类型和设计缓存元数据,已知的已知来源-time
- 通过与直接的(并且理想地异步)公知的方法变换运行
- 采取这一转换后的数据并将其装载到一个已知的目标还与已知的元数据
具有带回不同数据的参数化数据源很好。但是,要让他们每次都带回完全不同的元数据,而且不同套之间没有一致性,坦白地说,这很荒谬,而且我不完全确定我想知道在2008年包中如何处理所有列元数据。
这就是为什么它要求您将结果集添加到SSIS查询 - 因此它可以生成一些元数据。它在运行时不会这样做 - 它不能!它必须有一组已知的列(因为它将它们全部变换成编译变量)来处理。它期望每次运行数据流任务时使用相同的列 - 完全相同的列,直到名称,类型和约束。
这导致了一个(可怕的,可怕的)解决方案 - 只需将所有数据粘贴到一个临时表中,使用Column1,Column2 ... ColumnN,然后使用您用作表名参数的相同变量来有条件地分支你的代码,并做任何你想要的列。
另一个更理智的解决方案是为每个源表创建一个数据流任务,并在优先约束中使用您的参数来选择运行哪个数据流任务。
对于这个针对开箱即用的ETL定制的解决方案,您应该高度考虑只在C#或脚本任务中自行展开,而不是SSIS提供的数据流任务。
总之,请不要这样做。想想孩子们(包)!
这在理论上没有问题,但实际上,如果您有230个SSIS包需要升级到2012年,并且在2008年完成如此完美的数百个ole数据库源,那么您正在寻找一个快速解决方案。 – jdf35
我已经使用CozyRoc Dynamic DataFlow Plus来实现这一点。
使用配置表构建SQL Select语句,我有一个SSIS包将Oracle和Sybase(或任何OLEDB源)的数据加载到MS SQL中。一些结果集有数百万行,性能非常好。
每次需要新表格时,都可以在几分钟内完成配置,而不必在新的软件包中编写新的软件包,而是在经过预先测试的强大的现有软件包上运行。
没有它,我会一直写了数百包。
如果您尝试过'SET FMTONLY OFF; EXEC MyProc'在你的OLEDB源。这会让它变得更好吗? – billinkc
尝试过,但它不起作用。 SSIS需要元数据。 – jdf35
无赖。如果这个技巧适用于从2008年到2012年处理临时表的朋友。 – billinkc