我正在从源表到目标表的数据流。为了简化问题,我会说有两个合并的源表和一个目标表。此外,有一些主键可以帮助我识别每条记录
包每天都在运行,如果从源表中删除了一条记录,我怎么知道哪一条被删除,以便我可以在目标表中删除它?
(仅供参考!〜我已经检查目的地表中是否存在记录,如果是,则更新其他插入,但不知道如何查找已删除的数据)
答案 0 :(得分:0)
将源与目标进行比较的问题是,您必须在每次加载时将每个源行与目标进行比较,并且随着行数的增加,这会占用越来越多的时间。
因此,处理此问题的最佳方法可能是在源端。两个common approaches是“软删除”,您可以在其中设置标志列以将该行标记为已删除;或者在日志表中记录已删除行的PK的触发器(或将整行移动到存档日志表)。然后,您的ETL过程会查看标志或日志/存档表,以确定自上次加载以来哪些行已被删除。
另一种可能性是源平台提供了一些内置功能,可用于跟踪已删除的行,例如: SQL Server中的CDC。但是如果你对源数据库没有任何控制权(如果它甚至是一个数据库),那么除了比较完整的数据集之外别无选择。
答案 1 :(得分:0)
一种可能的方法:
优点:
您的目标表将始终镜像传入的数据,无需检查删除
缺点:
您将不会有任何历史信息(如果需要)
答案 2 :(得分:0)
另一种可能的方法:
假设您收到来自源的所有记录,而不仅仅是导入和更新:
修改包以标记使用唯一ID或运行日期时间插入或更新的记录
在程序包运行之后,处理目标表,其中未在最后一个程序包运行中插入或更新记录。通过消除过程,应删除源文件中未提供的任何记录。
同样,假设发送了所有记录,而不仅仅是导入和更新。但话说回来,如果你没有收到所有记录,那么在物理上不可能检测到记录是否已被删除。
答案 3 :(得分:-1)
我遇到了同样的问题,因为如何将我的旧/归档记录标记为“已删除”,因为它们不再存在于原始数据源中。
基本上,我建立了两个表,其中一个是包含来自原始数据源的所有记录的主表,还有一个临时表,每次运行脚本时,我都会保留该临时表来存储原始数据。
>主表
ID, NAME, SURNAME, DATE_MODIFIED, ORDERS_COUNT, etc
plus a STATUS column (1 for Active, 0 for Deleted)
TEMP TABLE (温度表)与原始记录相同,但没有STATUS列
ID, NAME, SURNAME, DATE_MODIFIED, ORDERS_COUNT, etc
关键是如果MAIN表的ID不再在Temp表中,则用 STATUS = 0 更新MAIN TABLE。即:源记录已被删除。
我是这样做的:
UPDATE m
SET m.Status = 0
FROM tblMAIN AS m
LEFT JOIN tblTEMP AS t
ON t.ID = m.ID
WHERE t.ID IS NULL