usage ejemplo current sql-server comparison timestamp inequality rowversion

ejemplo - SQL Server RowVersion/Timestamp-Comparaciones



sql server timestamp vs datetime (8)

Sé que el valor en sí de una columna RowVersion no es útil en sí mismo, excepto que cambia cada vez que se actualiza la fila. Sin embargo, me preguntaba si son útiles para la comparación relativa (desigualdad).

Si tengo una tabla con una columna RowVersion , cualquiera de las siguientes es verdadera:

  • ¿Todas las actualizaciones que se producen simultáneamente (la misma declaración de actualización o la misma transacción) tienen el mismo valor en la columna RowVersion ?
  • Si actualizo "A", seguido de la actualización "B", ¿las filas involucradas en la actualización "B" tendrán un valor mayor que las filas involucradas en la actualización "A"?

Gracias.


¿Qué te hace pensar que los tipos de datos Timestamp son malos? El tipo de datos es muy útil para la comprobación de concurrencia. Linq-To-SQL usa este tipo de datos para este propósito.

Las respuestas a tus preguntas:

1) No. Este valor se actualiza cada vez que se actualiza la fila. Si está actualizando la fila, digamos cinco veces, cada actualización incrementará el valor de Marca de tiempo. Por supuesto, te das cuenta de que las actualizaciones que "ocurren simultáneamente" realmente no. Todavía ocurren uno a la vez, alternadamente.

2) Sí.


Rowversion rompe uno de los enfoques "idealistas" de SQL: que una instrucción UPDATE es una acción atómica única y actúa como si todas las ACTUALIZACIONES (tanto para todas las columnas dentro de una fila, como para todas las filas dentro de la tabla) ocurrieran "en el Mismo tiempo". Pero en este caso, con Rowversion, es posible determinar que una fila se actualizó en un momento ligeramente diferente a otro.

Tenga en cuenta que el orden en que se actualizan las filas (mediante una sola declaración de actualización) no está garantizado; puede, por coincidencia, seguir el mismo orden que la clave agrupada para la tabla, pero no cuento con que sea cierto.


Desde MSDN :

Cada base de datos tiene un contador que se incrementa para cada inserción o operación de actualización que se realiza en una tabla que contiene una columna rowversion dentro de la base de datos. Este contador es la rowversion la base de datos. Esto rastrea un tiempo relativo dentro de una base de datos, no un tiempo real que pueda asociarse con un reloj. Cada vez que se modifica o inserta una fila con una columna rowversion , el valor incrementado de la rowversion base de datos se inserta en la columna rowversion .

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

  • Por lo que yo entiendo, nada REALMENTE ocurre simultáneamente en el sistema. Esto significa que todas las rowversion s deben ser únicas. Me atrevo a decir que serían efectivamente inútiles si se permitieran duplicados dentro de la misma tabla. Además, la credencia de rowversion s no duplicada es la postura de MSDN al no usarlos como claves primarias, no porque podría causar violaciones, sino porque podría causar problemas con las claves externas.
  • Según MSDN, "el tipo de datos rowversion es solo un número creciente ..." así que sí, más tarde es más grande.

A la pregunta de cuánto aumenta, dice MSDN, "[ rowversion ] rastrea un tiempo relativo dentro de una base de datos", lo que indica que no se trata de un incremento de entero fluido, sino de tiempo. Sin embargo, este "tiempo" no revela exactamente cuándo, sino más bien cuando, en relación con otras filas , se insertó / modificó una fila.


Alguna información adicional. RowVersion se convierte muy bien en bigint y, por lo tanto, uno puede mostrar una salida mejor legible cuando se depura:

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


Cada base de datos tiene un contador que se incrementa de a uno en cada modificación de datos que se realiza en la base de datos. Si la tabla que contiene la fila afectada (por actualización / inserción) contiene una columna de marca de tiempo / cambio de fila, el valor actual del contador de la base de datos se almacena en esa columna del registro actualizado / insertado.


Para responder a una parte de su pregunta: puede terminar con valores duplicados de acuerdo con MSDN:

Los valores de row row duplicados se pueden generar utilizando la instrucción SELECT INTO en la que una columna rowversion está en la lista SELECT. No recomendamos usar rowversion de esta manera.

Fuente: rowversion (Transact-SQL)


Pasé años tratando de resolver algo con esto, para pedir columnas actualizadas después de un número de secuencia particular. La marca de tiempo es en realidad solo un número de secuencia; también es bigendiano cuando las funciones de c # como BitConverter.ToInt64 quieren littleendian.

Terminé creando una vista db en la tabla de la que quiero datos con una columna de alias ''SequenceNo''

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

El código c # ve primero la vista (es decir, el UsuarioV) de forma idéntica a una tabla normal

luego en mi linq puedo unirme a la vista y tabla padre y comparar con un número de secuencia

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

para obtener lo que quiero, todas las entradas han cambiado desde la última vez que revisé.


Al igual que una nota, la timestamp está en desuso en SQL Server 2008 en adelante. rowversion debe usar en su lugar.

Desde esta página en MSDN:

La sintaxis timestamp está en desuso. Esta característica se eliminará en una versión futura de Microsoft SQL Server. Evite usar esta característica en nuevos trabajos de desarrollo y planee modificar las aplicaciones que actualmente usan esta característica.