我有一个数据仓库和一个临时数据库。登台每天在ftp上获取一个新文件,该文件将加载到登台DB上。然后在数据库仓库中插入/更新/删除它。但是,登台文件只有最近5天的记录,这些记录是滚动的。也就是说,从8/8到8/13将是今天,但明天该文件将具有从8/9到8/14的数据,而DB仓库具有所有历史记录。
当我使用
时WHEN NOT MATCHED BY SOURCE THEN DELETE
它会删除DBwarehouse中与登台不匹配的所有记录。这将消灭所有的历史。我想控制脚本仅在5天后返回并检查它是否与源不匹配。这是查询:
MERGE INTO
[x].[y].[z] AS Target
USING [a].[y].[z]AS Source
ON target.[PROBLEM_ID] =source.[PROBLEM_ID]
WHEN MATCHED THEN
UPDATE SET
Target.[CUSTNO] = Source.[CUSTNO],
Target.[SALESID] = Source.[SALESID],
Target.[PCODE] = Source.[PCODE]
WHEN NOT MATCHED BY TARGET THEN
INSERT
([CUSTNO]
,[SALESID]
,[PCODE])
VALUES
(source.[CUSTNO]
,source.[SALESID]
,source.[PCODE])
WHEN NOT MATCHED BY SOURCE
THEN DELETE;
;
我是否可以在删除语句上获得约束,仅在数据库仓库上返回5天?如果是,请帮助我使用约束代码。
答案 0 :(得分:0)
我没有尝试过这个,但是documentation说你可以在“不与来源匹配”中添加“AND”条款。这可以让你这样做:
WHEN NOT MATCHED BY SOURCE AND Your_Date_Field > DateAdd(Day,-5,GetDate())
THEN DELETE;
请注意,如果您的日期包含时间,则可能需要在比较日期之前截断时间。
答案 1 :(得分:0)
这基本上是你想要做的。您使用公用表表达式来构建要合并的更复杂的集合。您还可以在匹配时和不匹配时执行“和”操作,但我发现首先使用为cte目的构建的数据集开始更清晰。
和平 兆
with [merge_helper] ([custno], [salesid], [pcode])
as (select [source].[id],
[source].[custno],
[source].[salesid],
[source].[pcode]
from [a].[y].[z] as [source]
left join [x].[y].[z] as [target]
on [target].[id] = [source].[id]
union
select [target].[id],
[target].[custno],
[target].[salesid],
[target].[pcode]
from [x].[y].[z] as [target]
where [target].[id] not in (select [id]
from [source]))
merge into [x].[y].[z] as target
using [merge_helper] as source
on target.[id] = source.[id]
when matched then
update set target.[custno] = source.[custno],
target.[salesid] = source.[salesid],
target.[pcode] = source.[pcode]
when not matched by target then
insert ([custno],
[salesid],
[pcode])
values (source.[custno],
source.[salesid],
source.[pcode])
when not matched by source then
delete;