我有一个存储过程作为 SQL 命令文本,它正在传递一个包含表名的参数。然后该过程从该表返回数据。我无法直接将该表调用为 OLE DB 源,因为过程中的结果集需要发生一些业务逻辑。在 SQL 2008 中这工作得很好。在升级的 2012 包中,我得到“无法确定元数据,因为...包含动态 SQL。请考虑使用WITH RESULT SETS 子句来显式描述结果集。”
问题是我无法在过程中定义字段名称,因为作为参数传递的表名称可能是不同的值,并且每次生成的字段都可能不同。有人遇到这个问题或者有什么想法吗?我已经使用“dm_exec_describe_first_result_set”、临时表和包含 RESULT SETS 的 CTE 尝试了动态 SQL 的各种操作,但它在 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 数据流任务的每一个目的:
- 提取具有已知元数据的已知源,这些元数据可以在设计时静态类型化和缓存
- 通过直接(理想情况下是异步)转换来运行已知流程
- 获取转换后的数据并将其加载到也具有已知元数据的已知目的地
拥有带回不同数据的参数化数据源是很好的。但坦率地说,让他们每次都带回完全不同的元数据,而不同集之间没有一致性,这是荒谬的,而且我不完全确定我想知道您如何处理 2008 年工作包中的所有列元数据。
这就是为什么它希望您向 SSIS 查询添加一个WITH RESULTS SET - 这样它就可以生成一些元数据。它不会在运行时执行此操作 - 它不能!它必须有一组已知的列(因为无论如何它都会将它们全部别名化为编译变量)才能使用。每次运行该数据流任务时,它都期望相同的列 - 完全相同的列,包括名称、类型和约束。
这导致了一个(可怕的、可怕的)解决方案 - 只需将所有数据粘贴到带有 Column1、Column2 ... ColumnN 的临时表中,然后使用与表名称参数相同的变量来有条件地分支代码并执行以下操作:无论你想要什么列。
另一个更明智的解决方案是为每个源表创建一个数据流任务,并在优先级约束中使用参数来选择应运行哪个数据流任务。
对于这种针对开箱即用 ETL 量身定制的解决方案,您还应该高度考虑在 C# 或脚本任务中自行部署,而不是使用 SSIS 提供的数据流任务。
简而言之,请不要这样做。想想孩子们(包裹)!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)