[英]Merge with primary key violation
我有一个基于文件的导入内容,用户可以在其中发布要导入数据库中的文件。 将插入新记录,并更新具有现有ID的记录。
发布ID为NAME 5 Silly的文件后
他们可以通过发布ID为NAME 5 Sally的新文件来更正此问题
我将文件的批量插入(C#Windows服务)插入了批量表(Sql Server Azure v12)。 这些文件可以包含数百万行,因此我想避免遍历行。 批量插入后,我有一个SP进行合并更新/插入并更新已经存在的行并插入新行。
我遇到的问题是,当用户发布新记录并更正同一文件中的同一记录时。 我在目标表上收到主键冲突。
有解决这个问题的好方法吗?
这是一个例子:
--drop table #bulk --drop table #target create table #bulk( id int, name varchar(10) )
insert into #bulk values (1,'John') insert into #bulk values (2,'Sally') insert into #bulk values (3,'Paul') insert into #bulk values (4,'Gretchen') insert into #bulk values (5,'Penny') insert into #bulk values (5,'Peggy') create table #target( id int not null, name varchar(10), primary key (id))
insert into #bulk values (1,'John') insert into #bulk values (2,'Sally') insert into #bulk values (3,'Paul') insert into #bulk values (4,'Gretchen') insert into #bulk values (5,'Penny') insert into #bulk values (5,'Peggy') create table #target( id int not null, name varchar(10), primary key (id))
merge #target as target using(select id, name from #bulk) as bulktable on target.id = bulktable.id when matched then update set target.name = bulktable.name when not matched then insert(id, name) values (bulktable.id, bulktable.name);
这将处理名称的最新值。
您需要一个用于#bulk的新创建脚本
CREATE TABLE #bulk
(
row_id int identity(1,1),
id int,
name varchar(10)
)
这是可以与新批量表一起使用的脚本:
;WITH CTE as
(
SELECT
id, name,
row_number() over (partition by id order by row_id desc) rn
FROM #bulk
), CTE2 as
(
SELECT id, name
FROM CTE
WHERE rn = 1
)
MERGE #target as target
USING CTE2 as bulktable
on target.id = bulktable.id
WHEN matched and
not exists(SELECT target.name except SELECT bulktable.name)
-- this will handle null values. Otherwise it could simply have been:
-- matched and target.name <> bulktable.name
THEN update
SET target.name = bulktable.name
WHEN not matched THEN
INSERT(id, name) VALUES (bulktable.id, bulktable.name);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.