使用不同源数据库

时间:2018-06-05 08:54:38

标签: sql-server ssis sql-server-2016 linked-server

我需要将数据负载从完全加载更改为增量,并且通过此更改,我们将重建整个ETL过程。

以下是数据源基础架构的现状:

我们有两个生产服务器(针对两种不同的产品),假设 P1 P2 。在 P1 上,我们的数据源是两个数据库:位于链接服务器 S1 上的 DB1 DB2 。在 P2 上,链接服务器 S1 上只有一个数据库 DB3 。将来会添加另一个用于P2的数据库DB4和添加的产品P3。服务器S1上有SQL视图,显示所有数据。

我们的ETL:

P1和P2的两个不同的SSIS项目,实际上只有连接字符串不同。 DB1和DB2直接在数据流任务中由 Union ALL SSIS组件合并。目前,SSIS包正在执行存储在任务中的SQL查询,对于P1的ETL的更改导致重做P2的ETL中的相同更改。 数据在P1上每天加载两次,在P2上每5分钟加载一次,数据加载所有内容都被截断并加载到两个数据仓库中的登台表中。

目标:

我们的目标是创建一个带参数化的通用ETL过程,允许我们在服务器P2上执行SQL时使用DB3,而在服务器P1上执行SQL时使用DB1 + DB2,可以将其扩展到P3 + DB4和DB3。我们还希望将SQL代码从包中移到存储过程中,因此从开发人员的角度来看,维护会更容易 我们还需要在P1上更频繁地进行ETL,但同时我们不允许在链接服务器上短时间内多次查询整个数据集,一旦数据集随时间变大,这将是P2上的问题。

我们想要避免的事情: 动态SQL。

在SSIS中创建增量数据加载和此类参数化的最佳实践是什么?我们一直与负责服务器S1的开发人员保持联系,如果我们需要任何类型的视图,他将能够提供它。

1 个答案:

答案 0 :(得分:2)

我将采取的一般模式是这样的。

我的控制流将识别与我们的项目关联的服务器上的数据库(Connection Manager = Source)

enter image description here

我在这里针对sys.databases展示了一个问题,因为您可以应用AND D.Name IN ('DB1', 'DB2', 'DB3');等标准

在S1上,该查询将返回2个值,在S2上仅返回1.

我们使用该数据库列表作为ForEach循环枚举器的源来“粉碎”结果。对于我们在原始查询(DB1,DB2)中标识的每个值,我们将更新Source ConnectionManager的InitialCatalog属性。在下面的参考答案中,我设置了ConnectionString属性,但您只想修改InitialCatalog。所以每个循环,指向的数据库都会改变。

ForEach枚举器中的数据流然后被简化为仅处理当前数据库,而不必担心该服务器是否有3个源数据库或1。

enter image description here

注意事项

源查询和数据类型必须在所有关联的数据库中兼容。数据流的结构在设计时设置,在运行时不能更改。

如果实体在数据库中是一致的,并且只是将列调用为不同的列,则在每个数据库中创建一个视图以确保实体名称一致,然后您可以避免使用动态SQL。

当包开始时,您需要提供Source连接字符串的初始值。这可以通过调用的SET属性来完成。

参考答案

探索这些概念的一些相关SSIS答案