Sql server 大容量插入到具有非标识的唯一ID列的SQL表中

Sql server 大容量插入到具有非标识的唯一ID列的SQL表中,sql-server,merge,Sql Server,Merge,我编写了一个使用MERGE在表中插入/更新数据的过程,但这是我的问题。表上也是主键列的ID列不是标识列。我找到了一种插入数据的方法,但可能会在PK中产生我不想要的缺口 这是我目前有效的代码 MERGE Table p USING (SELECT i.Col1, i.Col2, i.Col3, (SELECT ISNULL(MAX(ID), 0) FROM Table1 i) +

我编写了一个使用MERGE在表中插入/更新数据的过程,但这是我的问题。表上也是主键列的ID列不是标识列。我找到了一种插入数据的方法,但可能会在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)
ORDER BY ID上的行号将为我提供唯一的值,但如果20条记录中的10条得到更新,它将在其他插入的“我的ID”列中创建间隙

我试过了

(Select ISNULL(MAX(ID), 0) + 1 from Table)
但显然,只有在只有1条记录要插入时,这才会正常工作。批量操作不会对每个insert语句执行子查询,这会导致PK冲突

我无法将ID列更改为标识列,因为旧版应用程序仍将信息插入该表,如果我将其更改为标识列,则会失败


有谁能给我另一种方法来进行合并,而不必遍历整个表,单独执行每个更新/插入?

一个简单的解决方案是分两步合并。在第一步中,更新现有行。在第二步中,插入新行。这避免了间隙问题,因为第二步只执行插入操作。

假设

Declare @Max int
select @max=isnull(id,0) from table2

now inside using,

      select * ,@Max +ROW_NUMBER()over(order by (select 0))
      from Table2

明白了吗?

标识字段也有间隙。这不是您应该关心的问题。此查询无法工作,别名和我没有映射到表。我的错误是,我实际上在原始查询上有一个联接。我编辑了这本书question@OGHaza问题在于,它们可以从示例中具有10k+记录的表Table1中合并,这可能会在两个ID'之间产生10k的间隙s@Jaques,它可以工作。首先在合并之前获取最大值。然后在使用中以某种方式使用此最大变量值以增加1。尽管我正在自己尝试。有问题吗?如何排除插入部分中的现有列。添加一个where Col1 not in Select Col1 from Table?在不匹配时省略,然后从第一个查询中插入,在匹配时省略,然后从第二个查询中更新它不起作用。当它插入1并更新其余的时,ID从10729跳到21459。总记录数是10729英寸。好的,我想你需要一个where not exists子查询。你想举个例子吗?这正是我目前使用的方法。如果有更新,它仍然会造成差距