Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Server RowVersion/Timestamp - Comparisons

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.

like image 294
David Pfeffer Avatar asked Dec 17 '10 13:12

David Pfeffer


People also ask

Is Rowversion a timestamp?

ROWVERSION (TIMESTAMP) is an incrementing 8-byte binary number, and unlike Oracle TIMESTAMP data type, it does not store any datetime related information. You can use timestamp columns to build custom data replication and synchronization solutions.

What is Rowversion in SQL Server?

rowversion is generally used as a mechanism for version-stamping table rows. The storage size is 8 bytes. The rowversion data type is just an incrementing number and does not preserve a date or a time. To record a date or time, use a datetime2 data type.

Is timestamp unique in SQL Server?

timestamp is a data type that exposes automatically generated binary numbers, which are guaranteed to be unique within a database.

Is timestamp deprecated?

“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.” It's been there for quite some time.


5 Answers

From MSDN:

Each database has a counter that is incremented for each insert or update operation that is performed on a table that contains a rowversion column within the database. This counter is the database rowversion. This tracks a relative time within a database, not an actual time that can be associated with a clock. Every time that a row with a rowversion column is modified or inserted, the incremented database rowversion value is inserted in the rowversion column.

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

  • As far as I understand, nothing ACTUALLY happens simultaneously in the system. This means that all rowversions should be unique. I venture to say that they would be effectively useless if duplicates were allowed within the same table. Also giving credance to rowversions not being duplicated is MSDN's stance on not using them as primary keys not because it would cause violations, but because it would cause foreign key issues.
  • According to MSDN, "The rowversion data type is just an incrementing number..." so yes, later is larger.

To the question of how much it increments, MSDN states, "[rowversion] tracks a relative time within a database" which indicates that it is not a fluid integer incrementing, but time based. However, this "time" reveals nothing of when exactly, but rather when in relation to other rows a row was inserted/modified.

like image 185
Brad Avatar answered Oct 20 '22 06:10

Brad


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
like image 31
Peter Meinl Avatar answered Oct 20 '22 07:10

Peter Meinl


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.

like image 6
user1587804 Avatar answered Oct 20 '22 07:10

user1587804


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.

like image 5
Randy Minder Avatar answered Oct 20 '22 08:10

Randy Minder


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.

like image 5
Town Avatar answered Oct 20 '22 08:10

Town