我编写了一个使用MERGE
在表中插入/更新数据的过程,但这是我的问题。表中也是主键列的ID
列不是IDENTITY
列。我找到了一种插入数据的方法,但是可能会在PK中创建我不想要的空白。
这是我目前正常运作的代码。
MERGE Table p
USING (SELECT i.Col1,
i.Col2,
i.Col3,
(SELECT ISNULL(MAX(ID), 0) FROM Table1 i) +
ROW_NUMBER() OVER (ORDER BY ID) ID
) a(Col1, Col2, Col3, ID)
ON p.Col1 = a.Col1
WHEN MATCHED THEN UPDATE set p.Col2 = a.Col2, p.Col3 = a.Col3
WHEN NOT MATCHED THEN INSERT (ID, Col1, Col2, Col3)
VALUES (a.ID, a.Col1, a.Col2, a.Col3)
ROW_NUMBER() OVER (ORDER BY ID)
将为我提供唯一值,但如果20条记录中的10条得到更新,则会在其他插页上的ID列中创建间隙。
我试过
(Select ISNULL(MAX(ID), 0) + 1 from Table)
但显然只有插入一条记录才能正常工作。批量操作不会为每个插入语句执行子查询,这会导致PK违规。
我无法将ID
列更改为identity
列,因为旧版应用程序仍将信息插入到该表中,如果我将其更改为标识列,则会失败。
任何人都可以给我另一种方法来做Merge,而不必遍历整个表,分别执行每次更新/插入吗?
答案 0 :(得分:0)
一个简单的解决方案是分两步合并。在第一步中,更新现有行。在第二步中,插入新行。这避免了间隙问题,因为第二步仅插入。
答案 1 :(得分:0)
假设,
Declare @Max int
select @max=isnull(id,0) from table2
now inside using,
select * ,@Max +ROW_NUMBER()over(order by (select 0))
from Table2
得到了吗?