row_number num index 11g sql sql-server tsql rowid row-number

num - Equivalente de RowID de Oracle en SQL Server



select row index sql server (13)

¿Cuál es el equivalente de RowID de Oracle en SQL Server?


Consulte http://msdn.microsoft.com/en-us/library/aa260631(v=SQL.80).aspx En el servidor SQL, una marca de tiempo no es lo mismo que una columna DateTime. Esto se utiliza para identificar de manera única una fila en una base de datos, no solo una tabla, sino toda la base de datos. Esto se puede usar para concurrencia optimista. por ejemplo, UPDATE [Trabajo] SET [Name] = @ Name, [XCustomData] = @ XCustomData WHERE ([ModifiedTimeStamp] = @ Original_ModifiedTimeStamp AND [GUID] = @ Original_GUID

ModifiedTimeStamp garantiza que está actualizando los datos originales y fallará si se ha producido otra actualización en la fila.


De http://vyaskn.tripod.com/programming_faq.htm#q17 :

Oracle tiene un Rownum para acceder a las filas de una tabla usando el número de fila o la identificación de fila. ¿Hay algún equivalente para eso en SQL Server? ¿O cómo generar resultados con el número de fila en SQL Server?

No existe un equivalente directo al rownum o id de fila de Oracle en SQL Server. Estrictamente hablando, en una base de datos relacional, las filas dentro de una tabla no están ordenadas y una identificación de fila no tendrá sentido. Pero si necesita esa funcionalidad, considere las siguientes tres alternativas:

  • Agrega una columna de IDENTITY a tu mesa.

  • Use la siguiente consulta para generar un número de fila para cada fila. La siguiente consulta genera un número de fila para cada fila en la tabla authors de la base de datos pubs. Para que esta consulta funcione, la tabla debe tener una clave única.

    SELECT (SELECT COUNT(i.au_id) FROM pubs..authors i WHERE i.au_id >= o.au_id ) AS RowID, au_fname + '' '' + au_lname AS ''Author name'' FROM pubs..authors o ORDER BY RowID

  • Utilice un método de tabla temporal para almacenar todo el conjunto de resultados en una tabla temporal, junto con una identificación de fila generada por la función IDENTITY() . Crear una tabla temporal será costoso, especialmente cuando se trabaja con tablas grandes. Vaya por este enfoque, si no tiene una clave única en su tabla.


Deduje una mesa muy grande con muchas columnas y la velocidad es importante. Por lo tanto, uso este método que funciona para cualquier tabla:

delete T from (select Row_Number() Over(Partition By BINARY_CHECKSUM(*) order by %%physloc%% ) As RowNumber, * From MyTable) T Where T.RowNumber > 1


Echa un vistazo a la nueva función ROW_NUMBER . Funciona así:

SELECT ROW_NUMBER() OVER (ORDER BY EMPID ASC) AS ROWID, * FROM EMPLOYEE



Puede obtener el ROWID utilizando los métodos que se detallan a continuación:

1.Cree una nueva tabla con campo de incremento automático en ella

2.Utilice la función analítica Row_Number para obtener la secuencia en función de sus necesidades. Preferiría esto porque ayuda en las situaciones en las que desea el row_id en forma ascendente o descendente de un campo específico o una combinación de campos

Ejemplo: Row_Number () Over (Partición por Deptno ordenar por sal desc)

La muestra de arriba le dará el número de secuencia basado en el salario más alto de cada departamento. La publicación por es opcional y puede eliminarla según sus requisitos.



Si desea identificar de manera única una fila dentro de la tabla en lugar de su conjunto de resultados, entonces debe considerar el uso de algo así como una columna de IDENTIDAD. Consulte "Propiedad de IDENTIDAD" en la ayuda de SQL Server. SQL Server no genera automáticamente una ID para cada fila de la tabla como lo hace Oracle, por lo que debe tomarse la molestia de crear su propia columna de ID y obtenerla explícitamente en su consulta.

EDITAR: para la numeración dinámica de las filas del conjunto de resultados, ver a continuación, pero eso probablemente sería un equivalente para el ROWNUM de Oracle y supongo que de todos los comentarios en la página que desea el material anterior. Para SQL Server 2005 y posterior, puede usar la nueva función de Funciones de clasificación para lograr la numeración dinámica de filas.

Por ejemplo, hago esto en una consulta mía:

select row_number() over (order by rn_execution_date asc) as ''Row Number'', rn_execution_date as ''Execution Date'', count(*) as ''Count'' from td.run where rn_execution_date >= ''2009-05-19'' group by rn_execution_date order by rn_execution_date asc

Te regalaré:

Row Number Execution Date Count ---------- ----------------- ----- 1 2009-05-19 00:00:00.000 280 2 2009-05-20 00:00:00.000 269 3 2009-05-21 00:00:00.000 279

También hay un artículo sobre support.microsoft.com en filas de numeración dinámicas.


Si desea numerar permanentemente las filas en la tabla, no use la solución RID para SQL Server. Funcionará peor que Access en un antiguo 386. Para SQL Server, simplemente cree una columna IDENTITY y use esa columna como clave principal agrupada. Esto colocará un Integer B-Tree permanente y rápido en la tabla, y lo que es más importante, cada índice no agrupado lo usará para ubicar filas. Si intenta desarrollar en SQL Server como si fuera Oracle, creará una base de datos de bajo rendimiento. Necesita optimizar para el motor, no pretender que es un motor diferente.

Además, no use NewID () para rellenar la clave principal con GUID, matará el rendimiento de inserción. Si debe usar GUID, use NewSequentialID () como columna predeterminada. Pero INT aún será más rápido.

Si, por otro lado, simplemente desea numerar las filas que resultan de una consulta, use la función RowNumber Over () como una de las columnas de la consulta.


Tomé este ejemplo del ejemplo de MS SQL y puede ver que @ID se puede intercambiar con enteros o varchar o lo que sea. Esta era la misma solución que estaba buscando, así que la estoy compartiendo. ¡¡Disfrutar!!

-- UPDATE statement with CTE references that are correctly matched. DECLARE @x TABLE (ID int, Stad int, Value int, ison bit); INSERT @x VALUES (1, 0, 10, 0), (2, 1, 20, 0), (6, 0, 40, 0), (4, 1, 50, 0), (5, 3, 60, 0), (9, 6, 20, 0), (7, 5, 10, 0), (8, 8, 220, 0); DECLARE @Error int; DECLARE @id int; WITH cte AS (SELECT top 1 * FROM @x WHERE Stad=6) UPDATE x -- cte is referenced by the alias. SET ison=1, @id=x.ID FROM cte AS x SELECT *, @id as ''random'' from @x GO


Varias de las respuestas anteriores funcionarán en torno a la falta de una referencia directa a una fila específica, pero no funcionarán si se producen cambios en las otras filas de una tabla. Ese es mi criterio para el cual las respuestas son técnicamente cortas.

Un uso común de ROWID de Oracle es proporcionar un método (algo) estable de seleccionar filas y luego regresar a la fila para procesarlo (por ejemplo, para ACTUALIZARLO). El método para buscar una fila (combinaciones complejas, búsqueda de texto completo o navegación fila por línea y la aplicación de pruebas de procedimiento en comparación con los datos) puede no volverse a utilizar fácilmente o con seguridad para calificar la instrucción UPDATE.

El SQL Server RID parece proporcionar la misma funcionalidad, pero no proporciona el mismo rendimiento. Ese es el único problema que veo, y desafortunadamente el propósito de conservar un ROWID es evitar repetir una operación costosa para encontrar la fila en, por ejemplo, una tabla muy grande. No obstante, el rendimiento en muchos casos es aceptable. Si Microsoft ajusta el optimizador en una versión futura, se podría abordar el problema de rendimiento.

También es posible usar FOR UPDATE y mantener el CURSOR abierto en un programa de procedimiento. Sin embargo, esto podría resultar costoso en el procesamiento de lotes grandes o complejos.

Advertencia: incluso el ROWID de Oracle no sería estable si el DBA, entre el SELECT y el UPDATE, por ejemplo, fuera a reconstruir la base de datos, porque es el identificador de fila física. Por lo tanto, el dispositivo ROWID solo se debe usar dentro de una tarea con un buen alcance.


si solo quieres la numeración de filas básica para un pequeño conjunto de datos, ¿qué tal algo así?

SELECT row_number() OVER (order by getdate()) as ROWID, * FROM Employees


De los documentos de Oracle

Pseudocolumna ROWID

Para cada fila en la base de datos, la pseudocolumna ROWID devuelve la dirección de la fila. Los valores rowid de Oracle Database contienen información necesaria para ubicar una fila:

  • El número de objeto de datos del objeto
  • El bloque de datos en el archivo de datos en el que reside la fila
  • La posición de la fila en el bloque de datos (la primera fila es 0)
  • El archivo de datos en el que reside la fila (el primer archivo es 1). El número de archivo es relativo al espacio de tabla.

El equivalente más cercano a esto en SQL Server es el rid que tiene tres componentes File:Page:Slot .

En SQL Server 2008, es posible usar la columna virtual %%physloc%% no documentada y no %%physloc%% para ver esto. Esto devuelve un valor binary(8) con el ID de página en los primeros cuatro bytes, luego 2 bytes para ID de archivo, seguido de 2 bytes para la ubicación de ranura en la página.

La función escalar sys.fn_PhysLocFormatter o sys.fn_PhysLocCracker TVF se puede utilizar para convertir esto en una forma más legible

CREATE TABLE T(X INT); INSERT INTO T VALUES(1),(2) SELECT %%physloc%% AS [%%physloc%%], sys.fn_PhysLocFormatter(%%physloc%%) AS [File:Page:Slot] FROM T

Ejemplo de salida

+--------------------+----------------+ | %%physloc%% | File:Page:Slot | +--------------------+----------------+ | 0x2926020001000000 | (1:140841:0) | | 0x2926020001000100 | (1:140841:1) | +--------------------+----------------+

Tenga en cuenta que esto no se aprovecha con el procesador de consultas. Si bien es posible usar esto en una cláusula WHERE

SELECT * FROM T WHERE %%physloc%% = 0x2926020001000100

SQL Server no buscará directamente la fila especificada. En su lugar, realizará una exploración de tabla completa, evaluará %%physloc%% para cada fila y devolverá la que coincida (si corresponde).

Para invertir el proceso llevado a cabo por las 2 funciones mencionadas anteriormente y obtener el valor binary(8) correspondiente a los valores conocidos de Archivo, Página, Ranura, se puede utilizar lo siguiente.

DECLARE @FileId int = 1, @PageId int = 338, @Slot int = 3 SELECT CAST(REVERSE(CAST(@PageId AS BINARY(4))) AS BINARY(4)) + CAST(REVERSE(CAST(@FileId AS BINARY(2))) AS BINARY(2)) + CAST(REVERSE(CAST(@Slot AS BINARY(2))) AS BINARY(2))