Frage

Ich weiß, dass der Wert selbst für eine RowVersion Spalte ist nicht an und für sich nützlich, mit der Ausnahme, dass es jedes Mal ändert sich die Zeile aktualisiert wird. Aber ich frage mich, ob sie im Verhältnis zum (Ungleichheit) Vergleich nützlich ist.

Wenn ich eine Tabelle mit einer Spalte RowVersion habe, ist entweder die folgenden Bedingungen zutreffen:

  • Werden alle Updates, die gleichzeitig (entweder gleiche Update-Anweisung oder derselben Transaktion) den gleichen Wert in der Spalte RowVersion auftreten?
  • Wenn ich Update tun "A", gefolgt von update "B" werden die in Update beteiligt Reihen "B" haben einen höheren Wert als die in Update beteiligten Reihen "A"?

Danke.

War es hilfreich?

Lösung

Von MSDN :

hat jede Datenbank einen Zähler, ist erhöhte für jeden Einsatz oder zu aktualisieren Operation, die auf einem Tisch durchgeführt wird, die eine rowversion Spalte in der Datenbank enthält. Dieser Zähler ist die Datenbank rowversion. Erfasst eine relative Zeit innerhalb einer Datenbank, nicht eine tatsächlichen Zeit, die mit einem Takt zugeordnet werden können. Jedes Mal , die eine Zeile mit einer rowversion Spalte modifizierte oder eingefügt , inkrementiert Datenbank rowversion value in der rowversion Spalte eingefügt.

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

  • Soweit ich verstehe, nichts passiert eigentlich gleichzeitig im System. Dies bedeutet, dass alle rowversions sollte eindeutig sein. Ich wage zu sagen, dass sie effektiv nutzlos wäre, wenn Duplikate innerhalb der gleichen Tabelle erlaubt waren. Auch credance zu rowversions gibt nicht dupliziert wird Haltung der MSDN auf nicht mit ihnen als Primärschlüssel nicht, weil es Verletzungen verursachen würde, sondern weil es Fremdschlüssel zu Problemen führen würde.
  • Laut MSDN: „Der rowversion Datentyp ist nur eine fortlaufende Nummer ...“ so ja, später größer ist.

Auf die Frage von wie viel es Schritten, MSDN heißt es: „[rowversion] eine relative Zeit innerhalb einer Datenbank verfolgt“, die anzeigt, dass es keine Flüssigkeit ganzer Zahl erhöht wird, aber die Zeit basiert. Allerdings zeigt diese "Zeit" nichts, wenn genau , sondern wenn in Bezug auf andere Reihen eine Zeile wurde eingefügt / modifiziert werden.

Andere Tipps

Einige zusätzliche Informationen. RowVersion wandelt schön bigint und damit kann man besser lesbare Ausgabe anzuzeigen, wenn das Debuggen:

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 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.

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.

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.

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.

To answer part of your question: you can end up with duplicate values according to MSDN:

Duplicate rowversion values can be generated by using the SELECT INTO statement in which a rowversion column is in the SELECT list. We do not recommend using rowversion in this manner.

Source: rowversion (Transact-SQL)

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top