使用增量主键sql插入多行

时间:2012-12-12 17:57:55

标签: sql sql-server-2008 insert primary-key

INSERT INTO TABLE1 (COLUMN1, PRIMARY_KEY)
   SELECT 
      COLUMN1,
      (SELECT COALESCE(MAX(PRIMARY_KEY), 0) 
        FROM TABLE1) + 1 
   FROM 
      TABLE2

错误:

  

违反主键约束。无法在对象中插入重复键。

如何在第一行之后使主键增加?

我希望能够同时向该表添加项目列表,而不是将它们插入RBAR。

感谢您的帮助

3 个答案:

答案 0 :(得分:12)

INSERT INTO TABLE1 (COLUMN1, PRIMARY_KEY)
SELECT COLUMN1,
       (SELECT COALESCE(MAX(PRIMARY_KEY),0)
       FROM TABLE1) + row_number() over (order by 1/0)
FROM TABLE 2

仅对于此声明,ID将是连续的,例如如果Max(Primary Key)是99且它正在插入4条记录,它们将是100,101,102,103。如果同时插入多个进程,则很容易出现约束违规,但这并不是说它是任何比使用MAX()本身不安全的单个记录更糟糕。

答案 1 :(得分:2)

你可以试试这个:

DECLARE @CurrentPK INT
SELECT @CurrentPK(MAX(PRIMARY_KEY)

SELECT column1, ROW_NUMBER() OVER (ORDER BY column1) AS 'RowNumber'
INTO #temp
FROM Table2

INSERT INTO TABLE1
(COLUMN1, PRIMARY_KEY)
SELECT COLUMN1,@CurrentPK+RowNumber 
FROM #temp

当然为了防止竞争条件,你应该把它放在一个事务中并明确地锁定同时发生的其他插入。您最好的选择是使用try6 catch块以及事务处理的存储过程。

我希望您了解在这种情况下避免交易不是一种选择。如果您没有专门使用事务,则有两次tprocessses尝试使用相同的id号时。实际上,这就是为什么获取最后一个id号的方法不推荐的原因,因为使用它来创建数据库问题太容易了。我知道你坚持这个,但至少学会在将来不要使用这种短视反模式。

答案 2 :(得分:-1)

您不必检查最大密钥并将1增加1.将其设为IDENTITY(1,1) NOT NULL列,服务器将对其进行检查。然后使用;

INSERT INTO TABLE1 (COLUMN1)
SELECT COLUMN1
FROM TABLE 2