我正在使用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。
感谢您的任何建议。
答案 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)
如果您无法更改表格结构以使Id
为IDENTITY
列,那么这可能是您最好的选择:
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;
这适用于批量插入,而不仅仅是单个名称插入。