SQL Server: insert next available int

…衆ロ難τιáo~ 提交于 2020-01-12 22:28:09

问题


I'm dealing with a table in SQL Server that has a serial_no column, which is defined as a non null int. It doesn't appear to be an auto incrementing field, as if I leave that column out of my insert statement I get an error saying that the serial_no field cannot be null.

So how do I insert the next available number?

I tried this:

INSERT INTO mytable (serial_no) VALUES ( (SELECT MAX(serial_no)+1 FROM mytable))

but I get an error saying that subqueries cannot be used in this context.

EDIT: This table is used in an off the shelf product so I cannot change the design and make the serial_no column an auto increment.


回答1:


You can improve write concurrency with locking hints

INSERT INTO mytable (serial_no, value)
SELECT MAX (serial_no)+1, @value 
FROM mytable WITH (ROWLOCK, XLOCK, HOLDLOCK)

If performance is't important, try TABLOCKX in place of ROWLOCK, XLOCK

However, given this isn't safe either you need to retry

DECLARE @retry bit
SET @retry = 1

WHILE @Retry = 1
BEGIN
    BEGIN TRY
        INSERT INTO mytable (serial_no, value)
        SELECT MAX (serial_no)+1, @value 
        FROM mytable WITH (ROWLOCK, XLOCK, HOLDLOCK)

        SET @Retry = 0
    END TRY
    BEGIN CATCH
        IF ERROR_NUMBER() <> 2627  --PK violation
            RAISERROR ('blah', 16, 1)
    END CATCH
END

Or change to an IDENTITY column and do it properly...




回答2:


The error can be fixed by dropping the VALUES

INSERT INTO mytable (serial_no, value)

SELECT MAX(serial_no)+1 ,
@value 
FROM mytable)

But this is a bad idea. There's a race condition on MAX(serial_no)+1 (e.g. two Inserts get the same value for Max(Serial_no).

You're better off using an auto increment field. You could also create a table that stores the current next value and increment it instead of using max.




回答3:


INSERT INTO mytable (serial_no) SELECT MAX(serial_no)+1 FROM mytable



回答4:


Try it without VALUES:

INSERT INTO mytable (serial_no) SELECT MAX(serial_no)+1 FROM mytable


来源:https://stackoverflow.com/questions/4853361/sql-server-insert-next-available-int

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!