Freigeben über


rowversion (Transact-SQL)

Ein Datentyp, der automatisch generierte eindeutige, binäre Zahlen in einer Datenbank verfügbar macht. rowversion wird normalerweise als Mechanismus für die Erstellung einer Versionskennung von Tabellenzeilen verwendet. Die Speichergröße beträgt 8 Byte. Der rowversion-Datentyp ist nur eine inkrementelle Nummer und behält ein Datum oder eine Uhrzeit nicht bei. Zum Aufzeichnen eines Datums oder einer Uhrzeit verwenden Sie einen datetime2-Datentyp.

Hinweise

Jede Datenbank weist einen Zähler auf, der für jeden Einfügungs- oder Updatevorgang inkrementiert wird, der für eine Tabelle mit einer rowversion-Spalte in der Datenbank ausgeführt wird. Dieser Zähler ist die Datenbankzeilenversion. Hiermit wird ein relativer Zeitpunkt innerhalb einer Datenbank nachverfolgt, keine tatsächliche Zeit, die einer Uhr zugeordnet werden kann. Eine Tabelle kann nur eine rowversion-Spalte aufweisen. Jedes Mal, wenn eine Zeile mit einer rowversion-Spalte geändert oder eingefügt wird, wird der inkrementierte Wert der Datenbankzeilenversion in die rowversion-Spalte eingefügt. Daher sind rowversion-Spalten ungeeignete Kandidaten für Schlüssel, insbesondere für Primärschlüssel. Jede Aktualisierung der Zeile ändert den rowversion-Wert und somit auch den Wert des Schlüssels. Wenn die Spalte in einem Primärschlüssel verwendet wird, sind der alte Wert und somit auch alle Fremdschlüssel, die auf den alten Wert verweisen, nicht mehr gültig. Wenn in einem dynamischen Cursor auf die Tabelle verwiesen wird, ändern alle Aktualisierungen die Position der Zeilen im Cursor. Falls die Spalte in einem Indexschlüssel verwendet wird, generieren alle Aktualisierungen der Datenzeile auch Aktualisierungen des Index.

timestamp ist das Synonym für den rowversion-Datentyp und unterliegt der Verhaltensweise von Datentypsynonymen. Verwenden Sie in DDL-Anweisungen möglichst rowversion anstelle von timestamp. Weitere Informationen finden Sie unter Synonyme für Datentypen (Transact-SQL).

Der timestamp-Datentyp von Transact-SQL unterscheidet sich vom timestamp-Datentyp gemäß dem ISO-Standard.

HinweisHinweis

Die Syntax timestamp ist veraltet. Diese Funktion wird in zukünftigen Versionen von Microsoft SQL Server nicht mehr bereitgestellt. Verwenden Sie diese Funktion beim Entwickeln neuer Anwendungen nicht, und planen Sie das Ändern von Anwendungen, in denen es zurzeit verwendet wird.

In einer CREATE TABLE- oder ALTER TABLE-Anweisung müssen Sie keinen Spaltennamen für den timestamp-Datentyp angeben:

CREATE TABLE ExampleTable (PriKey int PRIMARY KEY, timestamp);

Wenn Sie keinen Spaltennamen angeben, generiert SQL Server Database Engine (Datenbankmodul) den timestamp-Spaltennamen. Das rowversion-Synonym folgt jedoch nicht diesem Verhalten. Wenn Sie rowversion verwenden, müssen Sie einen Spaltennamen angeben, z. B.:

CREATE TABLE ExampleTable2 (PriKey int PRIMARY KEY, VerCol rowversion) ;
HinweisHinweis

Doppelte rowversion-Werte können mithilfe der SELECT INTO-Anweisung generiert werden, bei der eine rowversion-Spalte in der SELECT-Liste vorhanden ist. rowversion sollte jedoch nicht auf diese Weise verwendet werden.

Eine rowversion-Spalte, die keine NULL-Werte zulässt, ist semantisch gleichwertig mit einer binary(8)-Spalte. Eine rowversion-Spalte, die NULL-Werte zulässt, ist semantisch gleichwertig mit einer varbinary(8)-Spalte.

Mithilfe der rowversion-Spalte einer Zeile können Sie auf einfache Weise ermitteln, ob ein Wert in der Zeile geändert wurde, seit er zuletzt gelesen wurde. Falls die Zeile geändert wurde, wird der rowversion-Wert aktualisiert. Falls die Zeile nicht geändert wurde, ist der rowversion-Wert unverändert, seitdem die Zeile zuletzt gelesen wurde . Verwenden Sie @@DBTS, um den aktuellen rowversion-Wert für eine Datenbank zurückzugeben.

Sie können einer Tabelle eine rowversion-Spalte hinzufügen, um die Integrität der Datenbank sicherzustellen, wenn mehrere Benutzer gleichzeitig Zeilen aktualisieren. Außerdem können Sie feststellen, wie viele und welche Zeilen aktualisiert wurden, ohne die Tabelle erneut abzufragen.

Nehmen Sie z. B. an, Sie erstellen eine Tabelle mit dem Namen MyTest. Sie laden einige Daten in die Tabelle, indem Sie die folgenden Transact-SQL-Anweisungen ausführen.

CREATE TABLE MyTest (myKey int PRIMARY KEY
    ,myValue int, RV rowversion);
GO 
INSERT INTO MyTest (myKey, myValue) VALUES (1, 0);
GO 
INSERT INTO MyTest (myKey, myValue) VALUES (2, 0);
GO

Anschließend können Sie die folgenden Transact-SQL-Beispielanweisungen verwenden, um während der Aktualisierung eine Steuerung durch vollständige Parallelität in der MyTest-Tabelle zu implementieren.

DECLARE @t TABLE (myKey int);
UPDATE MyTest
SET myValue = 2
    OUTPUT inserted.myKey INTO @t(myKey) 
WHERE myKey = 1 
    AND RV = myValue;
IF (SELECT COUNT(*) FROM @t) = 0
    BEGIN
        RAISERROR ('error changing row with myKey = %d'
            ,16 -- Severity.
            ,1 -- State 
            ,1) -- myKey that was changed 
    END;

myValue ist der rowversion-Spaltenwert für die Zeile, die die Zeit angibt, zu der Sie die Zeile zuletzt gelesen haben. Dieser Wert muss durch den tatsächlichen rowversion-Wert ersetzt werden. Ein Beispiel für den tatsächlichen rowversion-Wert ist 0x00000000000007D3.

Sie können die Transact-SQL-Beispielanweisungen auch in einer Transaktion ablegen. Indem Sie die @t-Variable im Gültigkeitsbereich der Transaktion abfragen, können Sie die aktualisierte myKey-Spalte der Tabelle abrufen, ohne die Tabelle MyTest erneut abzufragen.

Im Folgenden wird das gleiche Beispiel mit der timestamp-Syntax angeführt:

CREATE TABLE MyTest2 (myKey int PRIMARY KEY
    ,myValue int, TS timestamp);
GO 
INSERT INTO MyTest2 (myKey, myValue) VALUES (1, 0);
GO 
INSERT INTO MyTest2 (myKey, myValue) VALUES (2, 0);
GO
DECLARE @t TABLE (myKey int);
UPDATE MyTest2
SET myValue = 2
    OUTPUT inserted.myKey INTO @t(myKey) 
WHERE myKey = 1 
    AND TS = myValue;
IF (SELECT COUNT(*) FROM @t) = 0
    BEGIN
        RAISERROR ('error changing row with myKey = %d'
            ,16 -- Severity.
            ,1 -- State 
            ,1) -- myKey that was changed 
    END;