获取更新语句中的最新rowversion/timestamp值 - Sql Server

Sim*_*ane 6 t-sql sql-server concurrency optimistic-concurrency

我正在使用rowversion列来处理乐观并发,并希望在我完成更新时获取新的rowversion值,以便我的数据层具有最新值,并且可以执行另一个更新并获得并发异常(除非记录有被别人更新了).

我在更新后只是在数据层中进行了操作,但这不是非常有效或完全可靠.

对于下表:

CREATE TABLE PurchaseType
(
    PurchaseTypeCode nvarchar(20) NOT NULL PRIMARY KEY CLUSTERED (PurchaseTypeCode),
    Name nvarchar(50) NOT NULL,
    TS rowversion NOT NULL
)
Run Code Online (Sandbox Code Playgroud)

我试过了:

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
Run Code Online (Sandbox Code Playgroud)

但由于没有从其他人的更新获得rowverion值的可能性,并不完全满意.然后我在rowversion文档中遇到了OUTPUT语句(http://msdn.microsoft.com/en-us/library/ms182776.aspx/http://msdn.microsoft.com/en-us/library/ms177564.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
Run Code Online (Sandbox Code Playgroud)

这很好用.在我的基本测试中(仅运行10000次调用并对其进行计时),OUTPUT选项需要大约40%的时间,但仍然不到半毫秒.SET STATISTICS TIME ON没有花费任何可测量的时间.

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

我曾希望我可以使用类似于SCOPE_IDENTITY()的函数来识别标识列,但是找不到类似的东西.谁知道我错过了什么?

提前致谢.

Gui*_*rez 1

来自MSDN

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

  • 谢谢,我对此一无所知。除非我弄错了。在这种情况下它无法可靠地工作,因为它是数据库范围的(类似于 @@identity)而不是过程范围(类似于 SCOPE_IDENTITY())。 (2认同)