SQL Server RowVersion/Timestamp - 比较

Dav*_*fer 27 sql-server comparison inequality timestamp rowversion

我知道RowVersion列的值本身并不是有用的,除了它每次更新行时都会更改.但是,我想知道它们是否对相对(不平等)比较有用.

如果我有一个包含RowVersion列的表,则满足以下条件之一:

  • 同时发生的所有更新(相同的更新语句或同一事务)是否在RowVersion列中具有相同的值?
  • 如果我更新"A",然后更新"B",更新"B"中涉及的行是否具有比更新"A"中涉及的行更高的值?

谢谢.

Bra*_*rad 35

来自MSDN:

每个数据库都有一个计数器,该计数器针对在包含rowversion数据库中的列的表上执行的每个插入或更新操作递增.这个计数器是数据库rowversion.这会跟踪数据库中的相对时间,而不是可以与时钟关联的实际时间.每次一个行rowversion被修改或插入,所述递增数据库rowversion 被插入到rowversion柱中.

http://msdn.microsoft.com/en-us/library/ms182776.aspx

  • 据我所知,系统中并不会同时发生任何事情.这意味着所有rowversions都应该是唯一的.我冒昧地说,如果在同一个表格中允许重复,它们将毫无用处.对于rowversion不被复制的信誉也是MSDN不使用它们作为主键的立场,不是因为它会导致违规,而是因为它会导致外键问题.
  • 根据MSDN,"rowversion数据类型只是一个递增的数字......"所以是的,后来更大.

对于它增加多少的问题,MSDN声明,"[ rowversion]跟踪数据库中的相对时间",这表明它不是流体整数递增,而是基于时间.然而,这个"时间"揭示了什么的时候正好,而是当相对于其他行的行插入/修改.

  • @Davied,`rowversion`的基础是基于数据库的,这意味着该值以某种方式相对于数据库过去的一个点.是的,后来意味着在整个数据库中更大.将其视为**数据库范围的身份**值. (6认同)
  • 布拉德:但是"后来意味着更大"跨越多行,而不仅仅是同一行?从措辞来看,它似乎表明没有,但实验似乎暗示是的. (4认同)

Pet*_*inl 13

一些额外的信息.RowVersion很好地转换为bigint,因此在调试时可以显示更好的可读输出:

CREATE TABLE [dbo].[T1](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Value] [nvarchar](50) NULL,
    [RowVer] [timestamp] NOT NULL
) 

insert into t1 ([value]) values ('a')
insert into t1 ([value]) values ('b')
insert into t1 ([value]) values ('c')
select Id, Value,CONVERT(bigint,rowver)as RowVer from t1
update t1 set [value] = 'x' where id = 3
select Id, Value,CONVERT(bigint,rowver)as RowVer from t1
update t1 set [value] = 'y' 
select Id, Value,CONVERT(bigint,rowver)as RowVer from t1

Id  Value   RowVer
1   a   2037
2   b   2038
3   c   2039

Id  Value   RowVer
1   a   2037
2   b   2038
3   x   2040

Id  Value   RowVer
1   y   2041
2   y   2042
3   y   2043
Run Code Online (Sandbox Code Playgroud)

  • 时间戳是 MSSQL 上 rowversion 数据类型的同义词。但时间戳语法已弃用,并会在 Microsoft SQL Server 的未来版本中删除。 (2认同)

小智 6

我花了很多年的时间尝试用这个来解决问题 - 要求在特定序列号后更新列.时间戳实际上只是一个序列号 - 当像BitConverter.ToInt64这样的c#函数需要littleendian时,它也是bigendian.

我最终在表上创建了一个db视图,我希望数据来自别名列'SequenceNo'

SELECT     ID, CONVERT(bigint, Timestamp) AS SequenceNo
FROM         dbo.[User]
Run Code Online (Sandbox Code Playgroud)

c#代码首先看到视图(即UserV)与普通表相同

然后在我的linq中我可以加入视图和父表并与序列号进行比较

var users =  (from u in context.GetTable<User>()
                join uv in context.GetTable<UserV>() on u.ID equals uv.ID
                where mysequenceNo < uv.SequenceNo
                orderby uv.SequenceNo
                select u).ToList();
Run Code Online (Sandbox Code Playgroud)

得到我想要的 - 自上次检查以来所有条目都有所改变.


Ran*_*der 5

是什么让你认为Timestamp数据类型是邪恶的?数据类型对于并发检查非常有用.Linq-To-SQL为此目的使用此数据类型.

你的问题的答案:

1)否.每次更新行时都会更新此值.如果要将行更新为五次,则每次更新都会增加Timestamp值.当然,您意识到"同时发生"的更新实际上并非如此.它们仍然只能一次出现一个.

2)是的.


Tow*_*own 5

就像一个注释一样,timestamp在SQL Server 2008之后不推荐使用.rowversion应该用来代替.

从MSDN上的这个页面:

时间戳语法已被弃用.将在Microsoft SQL Server的未来版本中删除此功能.避免在新的开发工作中使用此功能,并计划修改当前使用此功能的应用程序.

  • 令人讨厌的是,SSMS 不能将 rowversion 识别为有效的数据类型,只能识别时间戳。 (2认同)