rowversion (Transact-SQL)

S’applique à : SQL ServerAzure SQL Database Azure SQL Managed Instance

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é comme mécanisme de marquage de version des lignes de tables. La taille de stockage est égale à 8 octets. Le type de données rowversion est seulement un numéro à incrémentation et ne permet pas de conserver une date ni 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. La valeur rowversion est incrémentée avec toute instruction de mise à jour, même si aucune valeur de ligne n’est modifiée. (Par exemple, si la valeur d’une colonne est égale à 5 et qu’une instruction de mise à jour définit la valeur 5, cette action est considérée comme une mise à jour même si aucune modification n’a été apportée et la valeur rowversion est incrémentée.)

timestamp est le synonyme du type de données rowversion et est soumis au comportement des synonymes des types de données. Dans les instructions DDL, utilisez rowversion au lieu de timestamp autant que 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 par la norme ISO.

Notes

La syntaxe timestamp est dépréciée. Cette fonctionnalité sera supprimée dans une version future de 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. Quand vous utilisez rowversion, vous devez spécifier un nom de colonne, par exemple :

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

Notes

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

Une colonne rowversion qui n’accepte pas la valeur Null est sémantiquement équivalente à une colonne binary(8). Une colonne rowversion qui accepte la valeur Null est sémantiquement équivalente à une colonne varbinary(8).

La colonne rowversion d’une ligne permet de déterminer facilement si une instruction de mise à jour a été exécutée sur la ligne depuis la dernière fois qu’elle a été lue. Si une instruction de mise à jour est exécutée sur la ligne, la valeur rowversion est mise à jour. Si aucune instruction de mise à jour n’est exécutée sur la ligne, la valeur rowversion est la même que la dernière fois qu’elle a été lue. 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 quand 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 un échantillon des instructions Transact-SQL suivantes pour implémenter un contrôle d'accès concurrentiel optimiste sur la table MyTest pendant la mise à jour. Le script utilise <myRv> pour représenter la valeur rowversion de la dernière fois que vous avez lu la ligne. Remplacez la valeur par la valeur rowversion réelle. Un exemple de valeur rowversion réelle est 0x00000000000007D3.

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

Vous pouvez également mettre l’échantillon d’instructions Transact-SQL dans une transaction. En interrogeant la variable @t dans l'étendue de la transaction, vous pouvez récupérer la colonne myKey mise à jour de la table sans réinterroger la table MyTest.

Voici le même exemple avec la syntaxe timestamp. Remplacez <myTS> par un horodatage réel.

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 = <myTS>;  
IF (SELECT COUNT(*) FROM @t) = 0  
    BEGIN  
        RAISERROR ('error changing row with myKey = %d'  
            ,16 -- Severity.  
            ,1 -- State   
            ,1) -- myKey that was changed   
    END;  

Voir aussi

ALTER TABLE (Transact-SQL)
CAST et CONVERT (Transact-SQL)
CREATE TABLE (Transact-SQL)
Types de données (Transact-SQL)
DECLARE @local_variable (Transact-SQL)
DELETE (Transact-SQL)
INSERT (Transact-SQL)
MIN_ACTIVE_ROWVERSION (Transact-SQL)
SET @local_variable (Transact-SQL)
UPDATE (Transact-SQL)