SQL Server RowVersion/Timestamp - Comparisons

2019-02-04 03:29发布

I know that the value itself for a RowVersion column is not in and of itself useful, except that it changes each time the row is updated. However, I was wondering if they are useful for relative (inequality) comparison.

If I have a table with a RowVersion column, are either of the following true:

  • Will all updates that occur simultaneously (either same update statement or same transaction) have the same value in the RowVersion column?
  • If I do update "A", followed by update "B", will the rows involved in update "B" have a higher value than the rows involved in update "A"?

Thanks.

8条回答
甜甜的少女心
2楼-- · 2019-02-04 03:37

Every database has a counter that is incremented one by one on every data modification that is done in the database. If the table containing the affected (by update/insert) row contains a timestamp/rowversion column, the current counter value of the database is stored in that column of the updated/inserted record.

查看更多
一夜七次
3楼-- · 2019-02-04 03:38

What makes you think Timestamp data types are evil? The data type is very useful for concurrency checking. Linq-To-SQL uses this data type for this very purpose.

The answers to your questions:

1) No. This value is updated each time the row is updated. If you are updating the row say five times, each update will increment the Timestamp value. Of course, you realize that updates that "occur simultaneously" really don't. They still only occur one at a time, in turn.

2) Yes.

查看更多
做个烂人
4楼-- · 2019-02-04 03:41

Some additional information. RowVersion converts nicely to bigint and thus one can display better readable output when debugging:

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
查看更多
可以哭但决不认输i
5楼-- · 2019-02-04 03:42

Just as a note, timestamp is deprecated in SQL Server 2008 onwards. rowversion should be used instead.

From this page on MSDN:

The timestamp syntax is deprecated. This feature will be removed in a future version of Microsoft SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use this feature.

查看更多
Root(大扎)
6楼-- · 2019-02-04 03:45

I spent ages trying to sort something out with this - to ask for columns updated after a particular sequence number. The timestamp is really just a sequence number - it's also bigendian when c# functions like BitConverter.ToInt64 want littleendian.

I ended up creating a db view on the table i want data from with an alias column 'SequenceNo'

SELECT     ID, CONVERT(bigint, Timestamp) AS SequenceNo
FROM         dbo.[User]

c# Code first sees the view (ie UserV) identically to a normal table

then in my linq I can join the view and parent table and compare with a sequence number

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();

to get what I want - all the entries changed since the last time I checked.

查看更多
时光不老,我们不散
7楼-- · 2019-02-04 03:45

Rowversion does break one of the "idealistic" approaches of SQL - that an UPDATE statement is a single, atomic action, and acts as if all UPDATEs (both to all columns within a row, and all rows within the table) occur "at the same time". But in this case, with Rowversion, it is possible to determine that one row was updated at a slightly different time than another.

Note that the order in which rows are updated (by a single update statement) is not guaranteed - it may, by coincidence follow the same order as the clustered key for the table, but I wouldn't count on that being true.

查看更多
登录 后发表回答