IF EXISTS 和 MERGE 语句
Posted
技术标签:
【中文标题】IF EXISTS 和 MERGE 语句【英文标题】:IF EXISTS and MERGE Statement 【发布时间】:2022-01-02 11:29:34 【问题描述】:我有数据从多个其他表流入一个表让我们说:Table_A 然后我有一个合并存储过程,它从表 A 中获取数据并将其与表 B 合并。
但是,似乎有些不对劲。如果我截断并加载数据,它工作正常,但如果我不截断和加载,并且只是每小时获取查询,我会收到错误消息
消息 8672,级别 16,状态 1,过程 Merge_Table_A,第 4 行 [批处理开始第 0 行] MERGE 语句多次尝试更新或删除同一行。当目标行匹配多个源行时会发生这种情况。 MERGE 语句不能多次 UPDATE/DELETE 目标表的同一行。优化 ON 子句以确保目标行最多匹配一个源行,或使用 GROUP BY 子句对源行进行分组。
我该如何克服这个问题?
我希望能够增量加载数据而不是截断加载,但同时有一个存储过程,可以更新或插入或不关心行是否已存在。
【问题讨论】:
你能提供你的示例代码和数据吗? 您对错误消息和解决方案有何困惑?您不能有多个与目标记录匹配的源记录,因此您需要合并您的源记录,以便在执行合并之前每个匹配的“键”只有一条记录 【参考方案1】:您的目标表中似乎有重复行,这些行是从您之前的运行中加载的。
注意:Merge 中的匹配不考虑在运行 Merge 时插入(甚至重复)的行。
下面是我的带有示例数据的复制示例:
表1:初始数据
表 2:目标表
合并声明:
MERGE tb2 AS Target
USING tb1 AS Source
ON Source.firstname = Target.firstname and
Source.lastname = Target.lastname
-- For Inserts
WHEN NOT MATCHED BY Target THEN
INSERT (firstname, lastname, updated_date)
VALUES (Source.firstname, Source.lastname, source.updated_date)
-- For Updates
WHEN MATCHED THEN UPDATE SET
Target.updated_date = Source.updated_date
-- For Deletes
WHEN NOT MATCHED BY Source THEN
DELETE;
执行 Merge 时,它会插入所有数据而没有任何错误。
tb1 中的新数据:
当我运行 Merge 语句时,它给了我和你一样的错误。
作为一种解决方法,使用以下选项之一,
如果可能,在 ON 子句中添加附加条件以唯一标识数据。
从源中删除重复项并将数据合并到 tb2 中,如下所示。
--temp table
drop table if exists #tb1;
select * into #tb1 from (
select *, row_number() over(partition by firstname, lastname order by firstname, lastname, updated_date desc) as rn from tb1) a
where rn = 1
MERGE tb2 AS Target
USING #tb1 AS Source
ON Source.firstname = Target.firstname and
Source.lastname = Target.lastname
-- For Inserts
WHEN NOT MATCHED BY Target THEN
INSERT (firstname, lastname, updated_date)
VALUES (Source.firstname, Source.lastname, source.updated_date)
-- For Updates
WHEN MATCHED THEN UPDATE SET
Target.updated_date = Source.updated_date
-- For Deletes
WHEN NOT MATCHED BY Source THEN
DELETE;
数据合并到tb2成功。
【讨论】:
以上是关于IF EXISTS 和 MERGE 语句的主要内容,如果未能解决你的问题,请参考以下文章
oracle insert if not exists 语句
避免多个 if exists, else if exits 用于内部使用的不同连接的语句
2022-11-21:第N高的薪水。表结构和数据的sql语句如下。请问sql语句如何写? DROP TABLE IF EXISTS employee; CREATE TABLE employee (