在SQL Server中返回值并更新行而没有“干扰”

时间:2011-04-04 08:37:45

标签: sql-server tsql

我有这个存储过程

CREATE PROCEDURE spGrabSerial
  @serial nvarchar(16) output
AS
BEGIN
  SET NOCOUNT ON;
  set @serial = (SELECT top 1 serial from tblSerial)
  update tblSerial set InUse = 1 where serial = @serial
END

如何确保没有其他程序在select和update之间抓取相同的序列?

2 个答案:

答案 0 :(得分:6)

假设SQL Server 2005+,您可以使用OUTPUT子句在一个原子操作中执行此操作(请参阅Using tables as Queues)。

 ;with cte as (
    select top(1) 
      serial, InUse
    from tblSerial with (rowlock, readpast)
    where InUse <> 1
    order by serial
   )
 update cte 
 set InUse = 1 
 output inserted.serial

修改刚刚提醒过一种可以直接分配到output参数而不使用OUTPUT子句的方法。

 with cte as (
    select top(1) 
      serial, InUse
    from tblSerial with (rowlock, readpast)
    where InUse <> 1
    order by serial
   )
 update cte 
 set InUse = 1, @serial = serial 

答案 1 :(得分:1)

确保在事务隔离级别“可重复读取”中运行它:

set transaction isolation level repeatable read

然后在事务中运行存储过程,它将与其他更改隔离。