Question

Je sais que la valeur elle-même pour une colonne de RowVersion n'est pas en soi utile, sauf qu'il change chaque fois que la ligne est mis à jour. Cependant, je me demandais si elles sont utiles pour la comparaison relative (l'inégalité).

Si j'ai une table avec une colonne de RowVersion, sont soit une des situations suivantes:

  • Est-ce que toutes les mises à jour qui se produisent simultanément (soit même déclaration de mise à jour ou même transaction) ont la même valeur dans la colonne RowVersion?
  • Si je fais la mise à jour « A », suivie par la mise à jour « B », les lignes seront impliquées dans la mise à jour « B » ont une valeur plus élevée que les lignes impliquées dans la mise à jour « A »?

Merci.

Était-ce utile?

La solution

De MSDN :

Chaque base de données comporte un compteur qui est incrémentée pour chaque insert ou update opération qui est effectuée sur une table qui contient une colonne de rowversion dans la base. Ce compteur est la base de données rowversion. Cela suit un temps relatif dans une base de données, pas un temps réel qui peut être associée à une horloge. Chaque fois une rangée avec une colonne de rowversion est modifié ou inséré , incrémentée base de données rowversion Valeur est inséré dans la colonne rowversion.

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

  • Pour autant que je comprends, rien ne se passe EFFECTIVEMENT simultanément dans le système. Cela signifie que tous les rowversions doivent être uniques. J'ose dire qu'ils seraient effectivement inutile si les doublons ont été autorisés dans la même table. Aussi donne credance à rowversions pas dupliquées est la position de MSDN sur ne pas les utiliser comme clés primaires non pas parce qu'elle causerait des violations, mais parce qu'il causerait des problèmes de clé étrangère.
  • Selon MSDN, « Le type de données rowversion est juste un nombre incrémenter ... » donc oui, est plus tard plus.

A la question de combien incrémente, états MSDN, « [rowversion] pistes un temps relatif dans une base de données » qui indique qu'il est pas un entier fluide incrémenter, mais le temps en fonction. Cependant, ce "temps" ne révèle rien quand exactement , mais plutôt quand par rapport aux autres lignes une ligne a été insérée / modifiée.

Autres conseils

Quelques informations supplémentaires. Rowversion convertit bien à BigInt et donc on peut afficher la sortie mieux lisible lors du débogage:

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

Je passé des heures à essayer de trier quelque chose avec cela - pour demander des colonnes mises à jour après un numéro de séquence particulière. L'horodatage est vraiment juste un numéro de séquence -. Il est également bigEndian quand c # fonctions comme BitConverter.ToInt64 veulent littleEndian

J'ai fini par créer une vue db sur la table que je veux des données à partir d'une colonne d'alias « de SequenceNo »

SELECT     ID, CONVERT(bigint, Timestamp) AS SequenceNo
FROM         dbo.[User]

c # code voit d'abord la vue (c.-à-userv) identique à une table normale

puis dans mon LINQ je peux rejoindre le point de vue et d'une table parent et comparer avec un numéro de séquence

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();

pour obtenir ce que je veux -. Toutes les entrées ont changé depuis la dernière fois que j'ai vérifié

Qu'est-ce que vous fait penser que les types de données timestamp sont mal? Le type de données est très utile pour le contrôle d'accès concurrentiel. LINQ to SQL utilise ce type de données dans ce but.

Les réponses à vos questions:

1) n Cette valeur est mise à jour chaque fois que la ligne est mise à jour. Si vous mettez à jour le mot de la ligne cinq fois, chaque mise à jour incrémenter la valeur Timestamp. Bien sûr, vous vous rendez compte que les mises à jour « se déroulent simultanément » vraiment pas. Ils se produisent toujours qu'un seul à la fois, à son tour.

2) Oui.

Tout comme une note, timestamp est dépréciée dans SQL Server 2008. rowversion doit être utilisé à la place.

De cette page sur MSDN :

  

La syntaxe timestamp est dépréciée. Cette fonctionnalité sera supprimée dans un   version future de Microsoft SQL Server. Évitez d'utiliser cette fonctionnalité dans   nouveaux travaux de développement, et un plan pour modifier les applications qui actuellement   utiliser cette fonction.

rowversion ne rompt l'un des « idéaliste » approche de SQL - qu'une instruction UPDATE est une seule action atomique, et agit comme si toutes les modifications (à la fois à toutes les colonnes dans une rangée, et toutes les lignes dans la table) se produisent "à la fois". Mais dans ce cas, avec rowversion, il est possible de déterminer qu'une ligne a été mis à jour à un autre moment que légèrement différent.

Notez que l'ordre dans lequel les lignes sont mises à jour (par une déclaration de mise à jour unique) n'est pas garanti - il peut, par hasard suivre le même ordre que la clé en cluster pour la table, mais je ne compterais pas qu'être vrai .

Pour répondre à une partie de votre question: vous pouvez vous retrouver avec des doublons selon MSDN:

  

en double des valeurs de rowversion peut être généré en utilisant le SELECT INTO   déclaration dans laquelle une colonne rowversion est dans la liste SELECT. Nous faisons   recommande de ne pas utiliser rowversion de cette manière.

Source: rowversion (Transact-SQL)

Chaque base de données a un compteur qui est incrémenté un par un sur toutes les modifications de données qui se fait dans la base de données. Si la table contenant la ligne affectée (par mise à jour / insert) contient une colonne timestamp / rowversion, la valeur courante du compteur de la base de données est stockée dans la colonne de la mise à jour / disque inséré.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top