根据组合主键的值读取增量数据

时间:2018-10-03 11:54:38

标签: mysql sql sql-server tsql ssis

我有一个OLTP(源),从那里必须将数据增量地移动到DWH(目标)。 源表在Loan_id,AssetID上具有一个复合主键,如下所示。

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

如果它是单个col主键,那么我将检查目标位置的列的最大值,然后从源中读取所有记录,其中主键值大于目标位置的最大值,但是由于它是一个复合主键,因此无法使用。

有什么想法可以使用T-SQL查询完成吗?

规格:源是MYSQL DB,目标是MSSQL2012。使用链接服务器进行连接。

2 个答案:

答案 0 :(得分:1)

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

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

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

基本上,您检查密钥是否在目标位置。

如果密钥存在,则为更新(匹配)。

如果键不存在(不匹配),则为插入键。

答案 1 :(得分: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,或将所有源记录带到Land / Stage表中的目标,然后在此处进行合并。这是尝试链接服务器的示例。

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;

如果您不使用整个记录集,则可能会丢失目的地中的记录。例如,您将从源中提取的结果集限制到登台表中,现在将登台表与最终目的地合并,超出目的地的任何内容都将在目的地中被删除。您可以通过使用Google的CTE限制目标来解决此问题:“合并为cte作为目标”。如果您有个约会日期,就可以进行过滤。

如果您有日期列,那将总是有帮助的,尤其是在插入或更新新记录时的某种“更改/更新日期”列。然后,您可以根据您的源筛选仅关注的记录。