批量插入SQL表,其中唯一ID列不是标识

时间:2014-02-18 10:06:14

标签: sql-server merge

我编写了一个使用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,而不必遍历整个表,分别执行每次更新/插入吗?

2 个答案:

答案 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

得到了吗?