有两种主要的方法:
- 查找转换 --> OLE DB 命令/OLE DB 目标
- 将所有数据加载到临时表并使用 SQL 执行 MERGE。
我的偏好是后者,因为更新是基于 SET 的,但我确实使用前者,我知道它将主要是插入。
使用前者,您最终会得到类似以下的数据流任务:
这是来自 OLTP 数据库的 OLE DB 源,然后它会查找您的 OLAP 数据库以检索代理键。如果没有匹配,它会简单地向 OLE DB 目标插入一条新记录,当有匹配时,它会进行条件拆分,如果有任何字段发生更改,它将使用 OLE DB 命令更新 OLAP 表。
显然它可能比这复杂得多,但这涵盖了最简单的示例。
您还可以使用渐变维度转换打开一个向导来为您创建数据流,这再次变得更加复杂:
如前所述,我的首选是暂存表和基于集合的更新,因为 OLE DB 命令是逐行执行的,因此如果您要更新数百万条记录,这将需要很长时间。您可以简单地在 OLAP 数据库上创建一个临时表,并使用简单的 OLE DB 源和目标将数据移入,然后使用MERGE 更新 OLAP 表:
MERGE OLAP o
USING Staging s
ON o.BusinessKey = s.BusinessKey
AND o.Type2SCD = s.Type2SCD
AND o.Active = 1
WHEN MATCHED AND o.Type1SCD != s.Type1SCD THEN
UPDATE
SET Type1SCD = s.Type1SCD
WHEN NOT MATCHED BY TARGET THEN
INSERT (BusinessKey, Type1SCD, Type2SCD, Active, EffectiveDate)
VALUES (s.BusinessKey, s.Type1SCD, s.Type2SCD, 1, GETDATE())
WHEN NOT MATCHED BY SOURCE AND o.Active = 1 THEN
UPDATE
SET Active = 0;
以上假设每个业务Key有一个活动记录,并且类型1和类型2都是缓慢变化的维度,它会在BusinessKey和Type2SCD不匹配的地方插入一条新记录,另外它会设置任何不匹配的记录在源表中处于非活动状态。当存在匹配但类型 1 SCD 不同时,这将被更新。
值得注意的是MERGE has it's downsides,您可能希望将基于集合的 upsert 编写为单独的 INSERT 和 UPDATE 语句。我遇到的一个主要问题是,在我的所有维度表上,我的 BusinessKey 字段 WHERE Active = 1 上有一个唯一的过滤索引,以确保只有一个活动记录,我编写的 MERGE 应该可以正常工作,但是在this connect item 中没有详细说明。尽管在我的 ETL 中的所有 MERGE 语句的末尾添加 OPTION (QUERYTRACEON 8790); 并不是世界末日,但这并不理想。