【问题标题】:Reading incremental data based on the value of composite Primary key根据复合主键的值读取增量数据
【发布时间】:2019-03-08 15:38:06
【问题描述】:

我有一个 OLTP(源),数据必须从该 OLTP(源)以增量方式移动到 DWH(目标)。 源表在 Loan_id、AssetID 上有一个复合主键,如下所示。

LOAN_ID, ASSETID, REC_STATUS
'12848','13170', 'F'

如果它是单个 col 主键,那么我会检查目标列的最大值,然后从源中读取主键值大于目标最大值的所有记录,但是因为它是一个复合主键,所以这不起作用。

知道如何使用 T-SQL 查询来完成吗?

规格:源是 MYSQL DB,目标是 MSSQL 2012。连接是使用链接服务器建立的。

【问题讨论】:

  • 我会敦促您阅读您的问题并问问自己,您是否能够仅根据您发布的内容来理解您所要求的内容。你想在这里做什么的细节方式为零。
  • 无论主键定义如何,您如何管理更新和删除?

标签: mysql sql sql-server tsql ssis


【解决方案1】:

您可以尝试一些方法。在处理链接服务器时不知道该设置的细节以及数据量,性能可能是个问题。

如果您不担心现有记录的更改或删除,一个简单的左外连接将为您提供尚未插入目标的任何记录:

SELECT          [s].[LOAD_ID]
              , [s].[ASSETID]
              , [s].[REC_STATUS]
FROM            [LinkedServer].[Database].[schema].[SourceTable] [s]
LEFT OUTER JOIN [DestinationTable] [d]
    ON [s].[LOAN_ID] = [d].[LOAN_ID]
       AND [s].[ASSETID] = [d].[ASSETID]
WHERE           [d].[LOAN_ID] IS NULL;

如果您担心更改,您仍然可以使用左外部并在目标中查找 NULL 或字段值的差异,但是您需要额外的更新语句。

SELECT          [s].[LOAD_ID]
              , [s].[ASSETID]
              , [s].[REC_STATUS]
FROM            [LinkedServer].[Database].[schema].[SourceTable] [s]
LEFT OUTER JOIN [DestinationTable] [d]
    ON [s].[LOAN_ID] = [d].[LOAN_ID]
       AND [s].[ASSETID] = [d].[ASSETID]
WHERE           [d].[LOAN_ID] IS NULL --Records from source not in destination
                OR (
                        --This evaluates those in the destination, but then checks for changes in field values.
                       [d].[LOAN_ID] IS NOT NULL
                       AND (
                               [s].[REC_STATUS] <> [d].[REC_STATUS]
                               OR [s].[SomOtherField] <> [d].[SomeOtherField]
                           )
                   );

--The above insert into some landing or staging table on the destination side and then you could do a MERGE.

如果我们需要担心删除。一条记录已从源中删除,您不再希望它在目标中。翻转左外层以查找目标中不再在源中的记录:

DELETE [d]
FROM           [DestinationTable] [d]
LEFT OUTER JOIN [LinkedServer].[Database].[schema].[SourceTable] [s]
    ON [s].[LOAN_ID] = [d].[LOAN_ID]
   AND [s].[ASSETID] = [d].[ASSETID]
WHERE           [s].[LOAD_ID] IS NULL;

您可以尝试使用合并来完成所有这些操作。在链接服务器上尝试 MERGE 或将所有源记录带到土地/阶段表中的目的地,然后在那里进行合并。这是尝试通过链接服务器的示例。

MERGE [DestinationTable] [t]
USING [LinkedServer].[Database].[schema].[SourceTable] [s]
ON [s].[LOAN_ID] = [d].[LOAN_ID]
   AND [s].[ASSETID] = [d].[ASSETID]
WHEN MATCHED THEN UPDATE SET [REC_STATUS] = [s].[REC_STATUS]
WHEN NOT MATCHED BY TARGET THEN INSERT (
                                           [REC_STATUS]
                                       )
                                VALUES ( [s].[REC_STATUS] )
WHEN NOT MATCHED BY SOURCE THEN DELETE;

在处理合并时,请注意以下语句:

WHEN NOT MATCHED BY SOURCE THEN DELETE;

如果您没有使用整个记录集,您可能会丢失目标中的记录。例如,您已将从源中提取的结果集限制到临时表中,现在将临时表与最终目标合并,除此之外的任何内容都将在您的目标中删除。您可以通过使用 CTE 限制您的目标来解决这个问题,谷歌:“合并到 cte 作为目标”。如果你有一个可以过滤的日期。

如果您有一个日期列,那总是有帮助的,尤其是在插入或更新新记录时的某种更改/更新日期列。然后,您可以根据您的来源筛选出您关心的那些记录。

【讨论】:

  • 这可以根据需要完美运行。非常感谢蒂姆:)
【解决方案2】:

增量负载通常有一个驱动它们的日期。

您可以在查找中使用复合键。这已经回答了很多次了。

添加查找并将测试更改为重定向不匹配(默认为失败)。

基本上你检查目标中是否存在密钥。

如果密钥存在,那么它就是一个更新(匹配)。

如果键不存在(不匹配),那么它是一个插入。

【讨论】:

  • 谢谢 - 我现在正在尝试。将向您更新我能够实现的目标。
猜你喜欢
  • 1970-01-01
  • 2019-09-22
  • 1970-01-01
  • 2019-06-08
  • 1970-01-01
  • 2021-07-16
  • 1970-01-01
  • 2012-08-04
  • 2019-09-26
相关资源
最近更新 更多