SQL Server乐观锁定-返回更改的时间戳值

SQL Server乐观锁定-返回更改的时间戳值,sql,tsql,stored-procedures,sql-server-2008-r2,ado,Sql,Tsql,Stored Procedures,Sql Server 2008 R2,Ado,我有一个实现乐观锁定的更新存储过程。存储过程如下所示: ALTER PROCEDURE [dbo].[usp_Test] @Id AS char(2), @recordTimestamp as timestamp ... BEGIN UPDATE XY .. WHERE ((Id = @Id) AND (recordTimeStamp = @recordTimestamp)) i

我有一个实现乐观锁定的更新存储过程。存储过程如下所示:

ALTER PROCEDURE [dbo].[usp_Test] 
    @Id AS char(2),
       @recordTimestamp as timestamp
       ...
BEGIN       
    UPDATE XY
           ..
          WHERE ((Id = @Id) AND (recordTimeStamp = @recordTimestamp))       

if @@rowcount = 0
begin
RAISERROR ('this row was changed by another user', 18, 1)
end

SELECT timeStamp from XY where Id = @Idend

有没有更简单的方法返回新的时间戳?我真的希望避免使用SELECT语句

假设您至少可以使用SQL Server 2005输出

或者使用表变量更紧密地反映原始查询行为的版本

DECLARE @Timestamp TABLE(stamp binary(8))

UPDATE XY
SET col='foo'
OUTPUT inserted.recordTimeStamp INTO @Timestamp
WHERE (Id = @Id) AND (recordTimeStamp = @recordTimestamp) 

if @@rowcount = 0
begin
RAISERROR ('this row was changed by another user', 18, 1)
end

SELECT stamp 
FROM @Timestamp

显然我是瞎的@@DBTShttp://msdn.microsoft.com/en-us/library/ms187366SQL.90.aspx 指挥是正确的选择

   ...
if @@rowcount = 0 
begin 
RAISERROR ('this row was changed by another user', 18, 1) 
end  
SELECT @@DBTS

这是最有效的。唯一的问题是,它跳过了最后一个if子句。->>如果@rowcount=0 begin RAISERROR“这一行已被另一个用户更改”,18,1 end@@rowcount在时间戳不匹配时仍将为零,因此仍将引发错误。如果输出一个空的结果集,那么您也知道它不匹配。您可以输出到@tablevariable中,然后在末尾从中进行选择。@Damien-是,它是空的。在这种情况下,它不会返回时间戳。我认为这是OP期望的结果,严重性为18error@Martin-是的,我在评论后意识到,如果更新成功,他正在寻找这个值。我最初把它理解为如何找出阻止我更新的新值的某种形式,但我意识到这也没有什么意义,因为你想知道其他列的值also@Damien-是的,没错。如果同时记录被更改,我想抛出一个错误。errorException是data Manager代码中的后一个caugt。不,我不这么认为。这看起来像是一个全局变量,而不是文档中的连接范围变量。如果您有并发性,它可以从完全不同的行返回值。OUTPUT子句是正确的方法。我会按照我的回答去做。如果由于某种原因,您的代码无法处理该问题,那么您需要将inserted.recordTimeStamp输出到@TableVariable中,然后在最后进行选择。是的,您是对的。全局变量@DBTS返回当前数据库上次使用的时间戳值VARBINARY。我冲错方向了。非常感谢。
   ...
if @@rowcount = 0 
begin 
RAISERROR ('this row was changed by another user', 18, 1) 
end  
SELECT @@DBTS