您可以尝试一些方法。在处理链接服务器时不知道该设置的细节以及数据量,性能可能是个问题。
如果您不担心现有记录的更改或删除,一个简单的左外连接将为您提供尚未插入目标的任何记录:
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 作为目标”。如果你有一个可以过滤的日期。
如果您有一个日期列,那总是有帮助的,尤其是在插入或更新新记录时的某种更改/更新日期列。然后,您可以根据您的来源筛选出您关心的那些记录。