Tengo un procedimiento almacenado que altera los datos del usuario de cierta manera. Lo paso user_id y hace lo suyo. Quiero ejecutar una consulta en una tabla y luego para cada user_id encuentro ejecutar el procedimiento almacenado una vez en ese user_id
¿Cómo escribiría una consulta para esto?
sql
sql-server
stored-procedures
MetaGuru
fuente
fuente
Respuestas:
usa un cursor
ADENDA: [Ejemplo de cursor MS SQL]
en MS SQL, aquí hay un artículo de ejemplo
tenga en cuenta que los cursores son más lentos que las operaciones basadas en conjuntos, pero más rápidos que los bucles while manuales; más detalles en esta pregunta SO
ANEXO 2: si va a procesar más que unos pocos registros, primero introdúzcalos en una tabla temporal y pase el cursor sobre la tabla temporal; esto evitará que SQL se convierta en bloqueos de tabla y acelere la operación
APÉNDICE 3: y, por supuesto, si puede incorporar lo que esté haciendo su procedimiento almacenado a cada ID de usuario y ejecutar todo como una sola declaración de actualización de SQL, sería óptimo
fuente
¡intenta cambiar tu método si necesitas hacer un bucle!
dentro del procedimiento almacenado principal, cree una tabla #temp que contenga los datos que necesita procesar. Llame al procedimiento almacenado secundario, la tabla #temp estará visible y podrá procesarla, con suerte trabajando con todo el conjunto de datos y sin un cursor o bucle.
esto realmente depende de lo que esté haciendo este procedimiento almacenado secundario. Si está ACTUALIZANDO, puede "actualizar desde" unirse a la tabla #temp y hacer todo el trabajo en una declaración sin un bucle. Lo mismo se puede hacer para INSERT y DELETEs. Si necesita hacer múltiples actualizaciones con IFs, puede convertirlas en múltiples
UPDATE FROM
con la tabla #temp y usar declaraciones CASE o condiciones WHERE.Cuando trabaje en una base de datos, intente perder la mentalidad de bucle, es una pérdida de rendimiento real, causará bloqueo / bloqueo y ralentizará el procesamiento. Si realiza un bucle en todas partes, su sistema no escalará muy bien y será muy difícil de acelerar cuando los usuarios comiencen a quejarse de actualizaciones lentas.
Publique el contenido de este procedimiento al que desea llamar en un bucle, y apostaría 9 de cada 10 veces, podría escribirlo para trabajar en un conjunto de filas.
fuente
Se necesitará algo así como sustituciones para sus tablas y nombres de campo.
fuente
Puedes hacerlo con una consulta dinámica.
fuente
¿No se puede hacer esto con una función definida por el usuario para replicar lo que sea que esté haciendo su procedimiento almacenado?
donde udfMyFunction es una función que realiza que toma la ID de usuario y hace lo que sea necesario hacer con ella.
Ver http://www.sqlteam.com/article/user-defined-functions para obtener más información.
Estoy de acuerdo en que los cursores realmente deben evitarse siempre que sea posible. ¡Y generalmente es posible!
(por supuesto, mi respuesta presupone que solo está interesado en obtener la salida del SP y que no está cambiando los datos reales. Me parece que "altera los datos del usuario de cierta manera" un poco ambiguo de la pregunta original, así que pensé en ofrecer esto como una posible solución. ¡Depende completamente de lo que estés haciendo!)
fuente
Use una tabla variable o una tabla temporal.
Como se mencionó anteriormente, un cursor es el último recurso. Principalmente porque usa muchos recursos, emite bloqueos y puede ser una señal de que simplemente no estás entendiendo cómo usar SQL correctamente.
Cree una variable de tabla como esta (si está trabajando con muchos datos o tiene poca memoria, use una tabla temporal en su lugar):
los
id
es importante.Reemplazar
parent
ychild
con algunos buenos datos, por ejemplo, identificadores relevantes o el conjunto completo de datos para ser operado.Insertar datos en la tabla, por ejemplo:
Declara algunas variables:
Y finalmente, cree un ciclo while sobre los datos en la tabla:
La primera selección obtiene datos de la tabla temporal. La segunda selección actualiza el @id.
MIN
devuelve nulo si no se seleccionaron filas.Un enfoque alternativo es hacer un bucle mientras la tabla tiene filas
SELECT TOP 1
y eliminar la fila seleccionada de la tabla temporal:fuente
Me gusta la forma de consulta dinámica de Dave Rincon, ya que no usa cursores y es pequeña y fácil. Gracias Dave por compartir.
Pero para mis necesidades en Azure SQL y con un "distintivo" en la consulta, tuve que modificar el código de esta manera:
Espero que esto ayude a alguien...
fuente