Sql server 正在update语句中获取最新的行版本/时间戳值-Sql Server

Sql server 正在update语句中获取最新的行版本/时间戳值-Sql Server,sql-server,tsql,concurrency,optimistic-concurrency,Sql Server,Tsql,Concurrency,Optimistic Concurrency,我使用rowversion列来处理乐观并发性,并希望在完成更新后返回新的rowversion值,以便我的数据层具有最新的值,并且可以执行另一个更新并获得并发异常(除非记录已由其他人更新) 我只是在做了一次更新之后在数据层做了一次get,但是这不是非常有效或者非常可靠 下表: CREATE TABLE PurchaseType ( PurchaseTypeCode nvarchar(20) NOT NULL PRIMARY KEY CLUSTERED (PurchaseTypeCode),

我使用rowversion列来处理乐观并发性,并希望在完成更新后返回新的rowversion值,以便我的数据层具有最新的值,并且可以执行另一个更新并获得并发异常(除非记录已由其他人更新)

我只是在做了一次更新之后在数据层做了一次get,但是这不是非常有效或者非常可靠

下表:

CREATE TABLE PurchaseType
(
    PurchaseTypeCode nvarchar(20) NOT NULL PRIMARY KEY CLUSTERED (PurchaseTypeCode),
    Name nvarchar(50) NOT NULL,
    TS rowversion NOT NULL
)
我试过:

CREATE PROCEDURE PurchaseType_UpdateWithGet
@PurchaseTypeCode nvarchar(20),
@Name nvarchar(50),
@TS rowversion OUTPUT    
AS

UPDATE PurchaseType
SET Name = @Name
WHERE PurchaseTypeCode = @PurchaseTypeCode
 AND TS = @TS

SELECT @TS = TS FROM PurchaseType WHERE PurchaseTypeCode = @PurchaseTypeCode
GO
但我并不完全高兴,因为可能无法从其他人的更新中获取rowverion值。然后我在rowversion文档中遇到了输出语句(http://msdn.microsoft.com/en-us/library/ms182776.aspx /)并尝试了以下方法:

CREATE PROCEDURE PurchaseType_UpdateWithOutput
@PurchaseTypeCode nvarchar(20),
@Name nvarchar(50),
@TS rowversion OUTPUT    
AS

DECLARE @Output TABLE (TS BINARY(8))

UPDATE PurchaseType
SET Name = @Name
    OUTPUT inserted.TS into @Output
WHERE PurchaseTypeCode = @PurchaseTypeCode
    AND TS = @TS

SELECT TOP 1 @TS = TS FROM @Output
GO
这很有效。在我最基本的测试中(仅运行10000个调用并计时),输出选项花费的时间大约要长40%,但仍然不到半毫秒。都没有在“设置统计时间”的情况下花费任何可测量的时间

我的问题是,有人知道更好/更简单的方法吗

我曾希望为标识列使用类似于SCOPE_IDENTITY()的函数,但找不到类似的函数。有人知道我是否遗漏了什么吗

提前感谢。

发件人:

@@DBTS返回当前数据库最后使用的时间戳值。 当一行具有时间戳列时,将生成一个新的时间戳值 已插入或更新


您的问题是在“更新”和“选择其他人”之间更新行。因此,如果在update语句之后进行选择,则不会得到相同的值。这是一个不可重复读取的问题。您应该在update语句中使用锁定提示(UPDLOCK)。此锁将允许读卡器(即共享锁),但会阻止写入器。所以在更新之后,您将得到相同的行。因此,您的存储过程应该是-

CREATE PROCEDURE PurchaseType_UpdateWithGet
@PurchaseTypeCode nvarchar(20),
@Name nvarchar(50),
@TS rowversion OUTPUT    
AS

UPDATE PurchaseType with (updlock)
SET Name = @Name
WHERE PurchaseTypeCode = @PurchaseTypeCode
 AND TS = @TS

SELECT @TS = TS FROM PurchaseType WHERE PurchaseTypeCode = @PurchaseTypeCode
GO

输出是检索INSERT上生成的任何值的方法(如果你问我的话,它包括IDENTITY…)好的,谢谢。有什么特别的原因让你喜欢输出而不是范围标识吗?它与多行inserts一起工作。我们知道,
输出
将失败。谢谢,我不知道这一点。除非我弄错了。在这种情况下,它不能可靠地工作,因为它是数据库范围的(类似于@identity),而不是过程的作用域(类似于SCOPE_identity())。您是对的,这是一个缺点。我想输出是唯一的出路。