Partager via


rowversion (Transact-SQL)

Type de données présentant des nombres binaires uniques automatiquement générés à l'intérieur d'une base de données. rowversion est généralement utilisé en tant que mécanisme d'affectation de version aux lignes de tables. La taille de stockage est de 8 octets. Le type de données rowversion est seulement un nombre incrémentiel et ne permet pas de conserver une date ou une heure. Pour enregistrer une date ou une heure, utilisez le type de données datetime2.

Notes

Chaque base de données dispose d'un compteur qui est incrémenté chaque fois qu'une opération d'insertion ou de mise à jour est effectuée dans une table contenant une colonne rowversion dans la base de données. Ce compteur est la base de données rowversion. Il suit une heure relative au sein d'une base de données, et non pas une heure réelle qui peut être associée à une horloge. Une table ne peut comporter qu'une seule colonne rowversion. Chaque fois qu'une ligne associée à une colonne rowversion est modifiée ou insérée, la valeur incrémentée rowversion de la base de données est insérée dans la colonne rowversion. Cette propriété fait de la colonne rowversion un candidat peu valable pour les clés, en particulier les clés primaires. En effet, toute mise à jour apportée à la ligne a pour effet de changer la valeur rowversion, et par conséquent de modifier la valeur de la clé. Si la colonne se trouve dans une clé primaire, l'ancienne valeur de clé n'est plus valide et les clés étrangères faisant référence à l'ancienne valeur ne sont plus valides. Si la table est référencée dans un curseur dynamique, toutes les mises à jour modifient la position des lignes dans le curseur. Si la colonne est une clé d'index, toutes les mises à jour apportées à la ligne de données génèrent également des mises à jour de l'index.

timestamp est le synonyme du type de données rowversion et suit le comportement des synonymes de types de données. Dans les instructions DDL, utilisez rowversion au lieu de timestamp là où c'est possible. Pour plus d'informations, consultez Synonymes des types de données (Transact-SQL).

Le type de données timestamp de Transact-SQL est différent du type de données timestamp défini dans la norme ISO.

[!REMARQUE]

La syntaxe timestamp est abandonnée. Cette fonctionnalité sera supprimée dans une prochaine version de Microsoft SQL Server. Évitez d'utiliser cette fonctionnalité dans de nouveaux travaux de développement et prévoyez de modifier les applications qui utilisent actuellement cette fonctionnalité.

Dans une instruction CREATE TABLE ou ALTER TABLE, il n'est pas nécessaire de spécifier un nom de colonne pour le type de données timestamp. Par exemple :

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

Si vous ne spécifiez pas de nom de colonne, le Moteur de base de données SQL Server génère le nom de colonne timestamp ; toutefois, le synonyme rowversion ne suit pas ce comportement. Lorsque vous utilisez rowversion, vous devez spécifier un nom de colonne, par exemple :

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

[!REMARQUE]

Des valeurs rowversion en double peuvent être générées lorsque l'instruction SELECT INTO est utilisée et qu'elle contient une colonne rowversion dans la liste SELECT. Nous déconseillons d'utiliser rowversion de cette façon.

Une colonne rowversion qui n'accepte pas les valeurs NULL est sémantiquement équivalente à une colonne binary(8). Une colonne rowversion qui accepte les valeurs NULL est sémantiquement équivalente à une colonne varbinary(8).

La colonne rowversion d'une ligne permet de déterminer rapidement si une valeur de la ligne a changé depuis la dernière fois qu'elle a été lue. Si une ligne fait l'objet d'une modification, la valeur rowversion est mise à jour. Si aucune modification n'est apportée à la ligne, la valeur rowversion est inchangée. Pour renvoyer la valeur actuelle rowversion pour une base de données, utilisez @@DBTS.

Vous pouvez ajouter une colonne rowversion à une table afin de mieux assurer l'intégrité de la base de données lorsque plusieurs utilisateurs mettent à jour des lignes en même temps. Vous pouvez souhaiter également savoir combien de lignes et quelles lignes ont été mises à jour sans réinterroger la table.

Par exemple, supposons que vous créez une table nommée MyTest. Vous insérez des données dans la table en exécutant les instructions Transact-SQL suivantes.

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

Vous pouvez utiliser ensuite les instructions Transact-SQL de l'exemple pour implémenter un contrôle d'accès concurrentiel optimiste sur la table MyTest pendant la mise à jour.

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 est la valeur de la colonne rowversion pour la ligne qui indique la dernière fois que vous avez lu la ligne. Cette valeur doit être remplacée par la valeur rowversion réelle. Exemple de la valeur rowversion réelle : 0x00000000000007D3.

Vous pouvez également mettre les instructions Transact-SQL de l'exemple dans une transaction. En interrogeant la variable @t dans l'étendue de la transaction, vous pouvez extraire la colonne myKey mise à jour de la table sans réinterroger la table MyTes.

Ce qui est suit est le même exemple utilisant la syntaxe timestamp :

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;