【问题标题】:SSIS- sqlcmd from variable and varying number of fields returned by sourceSSIS- sqlcmd 来自源返回的变量和不同数量的字段
【发布时间】:2015-02-05 00:05:32
【问题描述】:

SSIS - 支持我们产品的多个版本

我们的企业数据仓库整合了来自多个数据源的数据。我们有一个要求,我们应该能够同时支持从这些数据源的不同版本收集数据。

例如。客户安装了我们产品的三个不同版本 7.3、7.3.1 和 7.3.2。在这种情况下,数据仓库的版本为 7.3.2,但应该能够从数据源的先前版本中收集数据。

我们使用存储过程将数据从来源收集到我们的暂存区,然后我们将其转换并加载到仓库中。 SSIS 包的设计是,有一个主包为我们从源收集数据的每个表执行包。主包根据我们需要从中收集数据的源调用,如果在运行时有三个源,则主包将运行三个实例。这些包在仓库机器上运行以从源系统中提取数据。

我们希望在仓库中维护这些包的一个版本,并支持从不同的源版本收集数据。

挑战

  • 源系统上存储过程的签名在版本之间发生了变化
  • 这些存储过程在较新版本中返回了一些附加字段

例子

7.3 版本签名:[dbo].[PDW_GetMediaAgentSummary](@LastVersionID AS BIGINT, @InitializeDays 作为 INT = 60,@NextVersionID 作为 BIGINT 输出)

7.3 Sp1 版本签名:[dbo].[PDW_GetMediaAgentSummary](@LastVersionID AS BIGINT, @DataStartDate 作为 DateTime2(3),@NextVersionID 作为 BIGINT 输出)

另外,假设在 7.3 这个存储过程返回 8 个字段,而 7.3 sp1 它返回 10 个字段。

我们尝试适应的方式是使用 OLE DB 源中的“SQLCmd from variable”选项来覆盖签名差异,但是该选项不允许我们将参数绑定到变量以获取输出值。第二个附加字段问题(或 7.3 过程中缺少附加字段),我们尝试关闭元数据验证,但是当我们针对 7.3 版本运行 SSIS 包时,在运行时出现 field not found 错误。看起来我们可以解决的唯一方法是根据源版本复制数据流任务。寻找更好的方法来做到这一点,因为随着版本数量的增加,这可能会失控。

感谢您对此的帮助

【问题讨论】:

  • 除了“不要改变你的方法签名”这一明显的事后评论之外,我会看一下尼克建议的内容。使用像 Biml 这样的东西来创建元数据驱动的包开发方法。您已经捕获了v7.3 is bigint, int, bigint outputv7.3 sp1 is bigint, datetime2(3), bigint output,因此与其在一些没有人看的文档中腐烂,不如对其进行操作。将其放入驱动程序包创建的结构中。您的主包确定要调用的包的版本,然后您将它们全部运送。
  • LOL 在某些文档中腐烂。所以非常真实。更糟糕的是:坐在一些过时的文件中伪装成真相!

标签: ssis parameterbinding


【解决方案1】:

包与元数据非常紧密地绑定在一起,任何变通方法都会让人头疼。您可以对 BIML 进行一些调查,这是一种动态创建包的方式。

没有很好的方法来处理这个问题。这是一个特别丑陋的建议(只是为了突出选项并真正指出缺点):

  • 在您的数据仓库中维护一个“适用于所有版本”的暂存表(具有跨所有版本的所有必需列)

  • 在一个包中为每个版本保留单独的数据流

  • 使用包中的逻辑(可能包括 .Net 脚本任务 bleeergh 或针对系统目录的查询)计算版本并仅运行正确的数据流

    李>
  • 根据已知版本处理“一刀切”表中的数据

还有其他变化。

但我认为这将是一场噩梦。

另一个选择是每个站点都有一个正确的“构建”(?)每个包的版本不同,并且只为站点的运行时部署正确的版本。这就是应用程序的工作方式——您拥有基于各种组件的完整“构建”。在您的情况下,构建由不同的包组成。

您的版本变体在一个包中定义(尽管每个源有许多包)

另一个难题:您可以通过在调用前添加以下内容来停止一些存储过程列返回问题:

SET FMTONLY OFF;

简而言之,这就是说'不要尝试并预先猜测存储过程中返回的列,只需运行它并使用实际返回的内容'

我们已经使用它来解决包在设计和运行时一直失败的问题,因为 SSIS认为存储过程没有返回任何列(基于运行前 SET FMTONLY ON; 的 SSIS),事实上,SP 执行时返回列。

【讨论】:

  • 非常感谢尼克。让我试试你的一些建议,然后回来。
  • 我们研究了上述建议。 BIML 看起来不错,但我们目前可能无法处理这种级别的变化。 SET FMTONLY OFF,仍然期望定义外部和输出列。我们还尝试了 "scriptcomponent as source" ,在脚本组件中基于我们可以填写值的版本,但与 "OleDB source" 相比,这花费了两倍的时间。任何原因,OleDB 源内部都应该做同样的事情,遍历结果集并填充输出缓冲区。我们也在尝试自定义 OleDB 源组件,它会表现得更好吗?
  • 我认为,当您构建足够的自定义脚本以允许一个包使用不同版本的源时,您可能已经构建了一个 C# 控制台应用程序。当你在做这样的动态事情时,SSIS 会迅速失去它的优势。我建议每个源版本使用一个包“构建”,它与元数据紧密绑定 - 即没有动态技巧,或者在 C# 中构建完全灵活的东西,涵盖所有版本
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 2013-11-28
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多