在SSIS 2012中的OLE DB源中使用动态SQL

时间:2013-10-29 18:54:29

标签: sql sql-server ssis dynamic-sql

我有一个存储过程作为SQL命令文本,它传递的参数包含一个表名。然后proc从该表返回数据。我不能直接将表调用为OLE DB源,因为某些业务逻辑需要发生在proc中的结果集中。在SQL 2008中,这很好用。在升级的2012软件包中,我得到“无法确定元数据,因为...包含动态SQL。请考虑使用WITH RESULT SETS子句明确描述结果集。”

问题是我无法在proc中定义字段名称,因为作为参数传递的表名可以是不同的值,并且结果字段每次都可以不同。有人遇到这个问题还是有什么想法?我使用动态SQL尝试了各种各样的事情,使用“dm_exec_describe_first_result_set”,临时表和包含WITH RESULT SETS的CTE,但它在SSIS 2012中不起作用,同样的错误。 Context是许多动态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 + '))')

2 个答案:

答案 0 :(得分:4)

所以我出于善意,为什么在上帝的绿色地球上你使用SSIS数据流任务来处理这样的动态源数据?

您遇到麻烦的原因是因为您正在歪曲SSIS数据流任务的所有目的:

  • 提取具有已知元数据的已知来源,该已知元数据可以在设计时静态输入和缓存
  • 以简单(理想的异步)转换方式运行已知流程
  • 获取已转换的数据,并使用已知元数据将其加载到已知目标

使用参数化的数据源可以带回不同的数据。但是,让它们每次都带回完全不同的元数据,并且不同组之间没有一致性,坦率地说,这很荒谬,而且我不完全确定我想知道你是如何在2008工作包中处理所有列元数据的。

这就是为什么它要为SSIS查询添加WITH RESULTS SET - 所以它可以生成一些元数据。它不会在运行时执行此操作 - 它不能!它必须有一组已知的列(因为它将它们全部归为已编译的变量)才能使用。它每次运行数据流任务时都需要相同的列 - 完全相同的列,直到名称,类型和约束。

这会导致一个(可怕的,可怕的)解决方案 - 只需将所有数据放入具有Column1,Column2 ... ColumnN的临时表中,然后使用您用作表名参数的相同变量来有条件地分支您的代码并用列做任何你想做的事。

另一个更合理的解决方案是为每个源表创建一个数据流任务,并在优先约束中使用您的参数来选择应该运行的数据流任务。

对于一个为开箱即用的ETL量身定制的解决方案,您还应该高度考虑在C#或脚本任务中滚动自己,而不是SSIS提供的数据流任务。

简而言之,请不要这样做。想想孩子们(包)!

答案 1 :(得分:1)

我使用CozyRoc Dynamic DataFlow Plus来实现这一目标。

使用配置表来构建SQL Select语句,我有一个SSIS包,可以将来自Oracle和Sybase(或任何OLEDB源)的数据加载到MS SQL。一些结果集有数百万行,性能非常好。

每次需要新表时,不需要编写新的包,而是可以在几分钟内完成配置,并在预先测试且强大的现有包上运行。

没有它我就会写出数百个包。