我有一个OLTP(源),从那里必须将数据增量地移动到DWH(目标)。 源表在Loan_id,AssetID上具有一个复合主键,如下所示。
LOAN_ID, ASSETID, REC_STATUS
'12848','13170', 'F'
如果它是单个col主键,那么我将检查目标位置的列的最大值,然后从源中读取所有记录,其中主键值大于目标位置的最大值,但是由于它是一个复合主键,因此无法使用。
有什么想法可以使用T-SQL查询完成吗?
规格:源是MYSQL DB,目标是MSSQL2012。使用链接服务器进行连接。
答案 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作为目标”。如果您有个约会日期,就可以进行过滤。
如果您有日期列,那将总是有帮助的,尤其是在插入或更新新记录时的某种“更改/更新日期”列。然后,您可以根据您的源筛选仅关注的记录。