SQL Server中生成的重复自动编号

时间:2012-02-23 22:48:32

标签: sql-server duplicates

温柔,我是一个SQL新手。我有一个名为autonumber_settings的表,如下所示:

Prefix | AutoNumber
SO     | 112320
CA     | 3542

每当创建新的销售行时,都会调用一个存储过程,该过程从“SO”行读取当前的自动编号值,然后递增该数字,更新该行,并从存储过程返回该数字。存储过程如下:

ALTER PROCEDURE [dbo].[GetAutoNumber]
(
    @type nvarchar(50) ,
    @out nvarchar(50) = '' OUTPUT
)
as
set nocount on

declare @currentvalue nvarchar(50)
declare @prefix nvarchar(10)

if exists (select * from autonumber_settings where lower(autonumber_type) = lower(@type))
begin
    select @prefix = isnull(autonumber_prefix,''),@currentvalue=autonumber_currentvalue 
    from autonumber_settings
    where lower(autonumber_type) = lower(@type)

    set @currentvalue = @currentvalue + 1

    update dbo.autonumber_settings set autonumber_currentvalue = @currentvalue where lower(autonumber_type) = lower(@type)
    set @out = cast(@prefix as nvarchar(10)) + cast(@currentvalue as nvarchar(50))
    select @out as value
end
else
    select '' as value

现在,还有另一个过程访问复制订单的同一个表,同时复制标题和行。有时,复制会导致重复的行号。这是一个程序:

BEGIN TRAN

IF exists
(
       SELECT *
       FROM autonumber_settings
       WHERE autonumber_type = 'SalesOrderDetail'
)
BEGIN
       SELECT
                @prefix = ISNULL(autonumber_prefix,'')
               ,@current_value=CAST (autonumber_currentvalue AS INTEGER)
       FROM autonumber_settings
       WHERE autonumber_type = 'SalesOrderDetail'

       SET @new_auto_number = @current_value + @number_of_lines

       UPDATE dbo.autonumber_settings
       SET autonumber_currentvalue = @new_auto_number
       WHERE autonumber_type = 'SalesOrderDetail'
END
COMMIT TRAN

关于为什么这两个程序似乎不能很好地结合起来的任何想法,偶尔会给出从头开始创建的相同行号作为复制创建的行。

2 个答案:

答案 0 :(得分:0)

这是竞争条件或您的自动编号。两个执行有可能在将新值写回数据库之前读出相同的值。

解决此问题的最佳方法是使用标识列并让SQL服务器处理自动编号分配。

除非您可以使用sp_getapplock序列化对autonumber_settings的访问权限。

答案 1 :(得分:0)

您可以对选择使用可重复读取。这将锁定行并阻止其他过程的选择,直到您更新值并提交。

在每个选择的from子句后插入WITH(REPEATABLEREAD,ROWLOCK)。