SQL Server:当表未设置为自动递增时,将值设置为下一个最高ID号

时间:2018-04-07 18:19:46

标签: sql sql-server

我正在使用SQL Server 2008,有时候使用SQL Server 2012,我需要在预先存在的数据库上进行插入,其中架构似乎没有为自动增量设置id列。

例如,我有一个基本的表My_Table

[Id]  [Name]
-------------
 1    JOHN
 2    BOB
 3    SALLY

我需要进行插入以获取最后一个Id的MAX值,然后将此值用于我的新插入语句。我相信这是最好的方法。

所以例如"伪语法"对于插入将是:

INSERT INTO My_Table 
VALUES(MAX(Id) + 1, 'MIKE');

如果未在表架构中设置Id以自动增加,那么最好的方法是什么?

注意:我正在使用Microsoft SQL Server。

感谢您的任何建议。

3 个答案:

答案 0 :(得分:4)

我建议更改表的结构以使用标识列。表定义应为:

create table my_table (
    id int identity(1, 1) primary key,
    . . .
);

这是正确的解决方案。如果你不能这样做,你可以表达逻辑:

insert to my_table (id, name)
     select coalesce(1 + max(id), 0), 'Mike'
     from my_table;

但是,这会受到竞争条件的影响。两个线程可以同时尝试插入并以相同的id结束。避免这种竞争条件是您希望数据库完成工作的原因。

如果您控制表中的所有插入,也可以使用序列。

答案 1 :(得分:2)

您可以使用IDENTITY列创建另一个表:

CREATE TABLE ID_Insert (
    ID INT IDENTITY(234, 1) primary key,
    Val smallint null
)

(您的种子值将为MAX(ID) + 1

在此表中插入任何值:

Insert ID_Insert(Val) values(NULL)

使用SCOPE_IDENTITY()获取插入值的ID,并将其插入到其他表中。

注意:我没有对此进行测试,但它解决了迄今为止提出的所有问题,因此欢迎任何批评。

答案 2 :(得分:0)

如果您无法更改表格结构以使IdIDENTITY列,那么这可能是您最好的选择:

SET XACT_ABORT ON;
BEGIN TRANSACTION;

DECLARE @maxId int = (SELECT MAX(id) FROM my_table);

INSERT INTO my_table (id, name)
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) + @maxId, name
    FROM my_other_table;

COMMIT TRANSACTION;

这适用于批量插入,而不仅仅是单个名称插入。