【发布时间】:2015-10-29 18:50:14
【问题描述】:
我目前正在编写一个 SSIS 包,它通过 OLE DB 源从存储过程中检索数据。存储过程包含一个相当讨厌的查询,我可以通过使用临时表来改进它。如果我将这些临时表切换到表变量,逻辑读取从大约 130 万跃升至大约 5600 万。我对 130 万次的逻辑读取感到很不自在,但我无法对 5600 万次逻辑读取感到满意。因此,我不能真正将临时表转换为表变量。
但是,SSIS(或者更确切地说是 SQL Server)无法解析此查询的元数据,因此包不会运行。我在网上找到了一些不同的解决方案,但它们似乎都不适用于 SQL Server 2008 和 SQL Server 2014。我们目前正在将所有服务器升级到 2014,这个特定的包在 2008 中运行DEV,2014 年在 QA,2008 年在生产中。到秋季,PROD 层级将是 2014 年,而 DEV 层级将在此之后的某个时间提升。不幸的是,我不能等到这些升级碰巧发布这个 SSIS 包。数据需要在下周开始移动。因此,我需要找到一种方法来为两种环境解析元数据。到目前为止,这是我尝试过的:
在返回正确元数据的
IF 1=0块中添加一个虚拟选择。这在 2008 年有效,但在 2014 年无效。在存储过程的开头使用
SET FMTONLY OFF。这在 2008 年有效,但在 2014 年无效。此外,它会导致存储过程为返回的每一列(在本例中超过 30 列)运行一次,即使它确实有效,也会破坏交易。使用
EXEC ... WITH RESULT SETS (( ... ));。这在 2014 年有效,但在 2008 年无效。部署返回正确元数据的存储过程,构建和部署 SSIS 包,然后将存储过程修改为正确版本。这似乎在这两种环境中都不起作用,这会使在我们的 ETL 框架内开发的任何其他 ETL 应用程序变得复杂。
如果我无法解决任何问题,我可以将不同的存储过程和包部署到不同的层,但我非常反对这样做。一方面,这会使未来的版本复杂化,而且我还需要确保在升级服务器后不会忘记更新存储过程和包。
我还可以在数据库中创建真正的表来代替这些临时表。我不是很喜欢这个解决方案,但这是我可以忍受的。如果我最终这样做,我将来可能会改用WITH RESULT SETS。
但是,我个人对这两种解决方案都不太在意,所以我想知道是否有任何我错过的解决方法可能会更好一些。
【问题讨论】:
-
优秀的第一篇文章,你已经清楚地完成了你的研究。在temp table versus table variable 上为您提供更多研究
-
您尝试过 1 和 3 的组合吗?一个同时具有
With Result Sets...和IF 1=0..的存储过程? -
您对 2008 年至 2012 年间 SSIS 如何处理临时表的重大变化一针见血。不过,刷新我的记忆,为什么 SSIS 包会发生变化?无论调用者是 2008 年还是 2014 年,它仍然会调用
dbo.MyProc。这只是需要针对环境进行更正的底层过程,是吗? -
使用包装存储过程怎么样?在两个 SSIS 服务器上,相同的 SSIS 代码调用相同的过程名称。在 2014 年,该 proc 使用 WITH RESULT SETS 调用执行实际工作的子 proc。在 2008 年,包装 proc 使用 IF 1=0 并调用相同的子 proc(或相同的 proc 代码,但在 2008 年)。
-
您是否尝试过将包的延迟验证设置为 true,以便在运行该步骤之前它不会查找元数据?
标签: sql-server sql-server-2008 ssis sql-server-2014