Digamos que tengo la siguiente variable de tabla simple:
declare @databases table
(
DatabaseID int,
Name varchar(15),
Server varchar(15)
)
-- insert a bunch rows into @databases
¿Declarar y usar un cursor es mi única opción si quisiera recorrer las filas? ¿Hay otra manera?
sql-server
tsql
loops
Rayo
fuente
fuente
STATIC
opción para eliminar la revisión constante de las tablas base y el bloqueo que están allí por defecto y hace que la mayoría de las personas crean erróneamente que los CURSORES son malos. @JacquesB muy cerca: volver a verificar para ver si la fila de resultados todavía existe + bloqueo son los problemas. YSTATIC
generalmente arregla eso :-).Respuestas:
En primer lugar, debe estar absolutamente seguro de que necesita recorrer cada fila: las operaciones basadas en conjuntos funcionarán más rápido en todos los casos que se me ocurran y normalmente utilizarán un código más simple.
Dependiendo de sus datos, puede ser posible realizar un bucle utilizando solo
SELECT
declaraciones como se muestra a continuación:Otra alternativa es usar una tabla temporal:
La opción que debe elegir realmente depende de la estructura y el volumen de sus datos.
Nota: Si está utilizando SQL Server, será mejor que utilice:
El uso
COUNT
tendrá que tocar cada fila de la tabla, laEXISTS
única necesita tocar la primera (ver la respuesta de Josef a continuación).fuente
STATIC
opción que copia el conjunto de resultados en una tabla temporal y, por lo tanto, ya no está bloqueando o volviendo a verificar las tablas base :-).Solo una nota rápida, si está utilizando SQL Server (2008 y superior), los ejemplos que tienen:
Sería mejor servido con
El Conde tendrá que tocar cada fila de la tabla,
EXISTS
solo necesita tocar la primera.fuente
Así es como lo hago:
Sin cursores, sin tablas temporales, sin columnas adicionales. La columna USERID debe ser un número entero único, como lo son la mayoría de las claves principales.
fuente
Defina su tabla temporal así:
Entonces haz esto -
fuente
Así es como lo haría:
[Editar] Debido a que probablemente omití la palabra "variable" cuando leí la pregunta por primera vez, aquí hay una respuesta actualizada ...
fuente
Si no tiene más remedio que ir fila por fila creando un cursor FAST_FORWARD. Será tan rápido como construir un ciclo while y mucho más fácil de mantener a largo plazo.
FAST_FORWARD Especifica un cursor FORWARD_ONLY, READ_ONLY con optimizaciones de rendimiento habilitadas. FAST_FORWARD no se puede especificar si SCROLL o FOR_UPDATE también se especifica.
fuente
FAST_FORWARD
cursor es una buena solución. (Otro enfoque sin tener que cambiar su esquema o usar tablas temporales:
fuente
Puedes usar un ciclo while:
fuente
Esto funcionará en la versión SQL SERVER 2012.
fuente
Ligero, sin tener que hacer tablas adicionales, si tiene un número entero
ID
en la mesafuente
fuente
Realmente no veo el punto por el que tendrías que recurrir al uso temido
cursor
. Pero aquí hay otra opción si está utilizando SQL Server versión 2005/2008Use Recursion
fuente
Voy a proporcionar la solución basada en conjuntos.
Esto es mucho más rápido que cualquier técnica de bucle y es más fácil de escribir y mantener.
fuente
Prefiero usar Offset Fetch si tiene una identificación única, puede ordenar su tabla por:
De esta manera, no necesito agregar campos a la tabla o usar una función de ventana.
fuente
Es posible usar un cursor para hacer esto:
la función create [dbo] .f_teste_loop devuelve la tabla @tabela (cod int, nome varchar (10)) como comienzo
final
crear procedimiento [dbo]. [sp_teste_loop] como comenzar
final
fuente
Estoy de acuerdo con la publicación anterior en que las operaciones basadas en conjuntos generalmente funcionarán mejor, pero si necesita iterar sobre las filas, este es el enfoque que tomaría:
Seleccione el siguiente registro no utilizado de la tabla y repita el proceso.
fuente
Paso 1: A continuación, la instrucción select crea una tabla temporal con un número de fila único para cada registro.
Paso 2: declara las variables requeridas
Paso 3: tome el recuento total de filas de la tabla temporal
Paso 4: tabla temporal de bucle basada en un número de fila único creado en temp
fuente
Este enfoque solo requiere una variable y no elimina ninguna fila de @databases. Sé que hay muchas respuestas aquí, pero no veo una que use MIN para obtener su próxima identificación como esta.
fuente
Aquí está mi solución, que utiliza un bucle infinito, la
BREAK
declaración y la@@ROWCOUNT
función. No se necesitan cursores ni tablas temporales, y solo necesito escribir una consulta para obtener la siguiente fila en la@databases
tabla:fuente
Este es el código que estoy usando 2008 R2. Este código que estoy usando es para construir índices en campos clave (SSNO y EMPR_NO) en todos los cuentos
fuente
seria mejor:
Evite usar SELECT si no hace referencia a tablas, solo asigna valores.
fuente