valor stored salida retornar procedimientos procedimiento parametros para mostrar fecha entrada ejemplo ejecutar devolver datos con almacenados almacenado sql sql-server stored-procedures

sql - stored - ¿Cómo ejecuto un procedimiento almacenado una vez para cada fila devuelta por la consulta?



procedimientos almacenados sql (6)

¿No se puede hacer esto con una función definida por el usuario para replicar lo que sea que esté haciendo su procedimiento almacenado?

SELECT udfMyFunction(user_id), someOtherField, etc FROM MyTable WHERE WhateverCondition

donde udfMyFunction es una función que realiza que toma la identificación del usuario y hace lo que tiene que hacer con ella.

Ver http://www.sqlteam.com/article/user-defined-functions para un poco más de fondo

Estoy de acuerdo en que los cursores realmente deberían evitarse siempre que sea posible. ¡Y usualmente es posible!

(Por supuesto, mi respuesta presupone que solo está interesado en obtener el resultado del SP y que no está cambiando los datos reales. Encuentro que "altera los datos del usuario de cierta manera" es 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!)

Tengo un procedimiento almacenado que altera los datos de usuario de cierta manera. Lo paso user_id y lo hace. 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 la consulta para esto?


Algo así como sustituciones serán necesarias para sus tablas y nombres de campo.

Declare @TableUsers Table (User_ID, MyRowCount Int Identity(1,1) Declare @i Int, @MaxI Int, @UserID nVarchar(50) Insert into @TableUser Select User_ID From Users Where (My Criteria) Select @MaxI = @@RowCount, @i = 1 While @i <= @MaxI Begin Select @UserID = UserID from @TableUsers Where MyRowCount = @i Exec prMyStoredProc @UserID Select @i = @i + 1, @UserID = null End


Me gusta la forma de consulta dinámica de Dave Rincon ya que no utiliza cursores y es pequeña y fácil. Gracias Dave por compartir.

Pero para mis necesidades en Azure SQL y con un "distinct" en la consulta, tuve que modificar el código de esta manera:

Declare @SQL nvarchar(max); -- Set SQL Variable -- Prepare exec command for each distinctive tenantid found in Machines SELECT @SQL = (Select distinct ''exec dbo.sp_S2_Laser_to_cache '' + convert(varchar(8),tenantid) + '';'' from Dim_Machine where iscurrent = 1 FOR XML PATH('''')) --for debugging print the sql print @SQL; --execute the generated sql script exec sp_executesql @SQL;

Espero que esto ayude a alguien...


Puedes hacerlo con una consulta dinámica.

declare @cadena varchar(max) = '''' select @cadena = @cadena + ''exec spAPI '' + ltrim(id) + '';'' from sysobjects; exec(@cadena);


usa un cursor

ADDENDUM: [Ejemplo de cursor MS SQL]

declare @field1 int declare @field2 int declare cur CURSOR LOCAL for select field1, field2 from sometable where someotherfield is null open cur fetch next from cur into @field1, @field2 while @@FETCH_STATUS = 0 BEGIN --execute your sproc on each row exec uspYourSproc @field1, @field2 fetch next from cur into @field1, @field2 END close cur deallocate cur

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 while-loops manuales; más detalles en esta pregunta SO

ADDENDUM 2: si va a procesar más que unos pocos registros, primero tire de ellos a una tabla temporal y pase el cursor sobre la tabla temporal; esto evitará que SQL se intensifique en bloqueos de tabla y acelere la operación

ADDENDUM 3: y, por supuesto, si puede alinear lo que sea que su procedimiento almacenado esté haciendo con cada ID de usuario y ejecutarlo todo como una sola declaración de actualización de SQL, sería óptimo


intenta cambiar tu método si necesitas hacer un ciclo

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 hijo. Si está ACTUALIZANDO, puede "actualizar desde" unirse en la tabla #temp y hacer todo el trabajo en una declaración sin un bucle. Lo mismo se puede hacer para INSERT y DELETE. Si necesita hacer varias actualizaciones con IFs, puede convertirlas a varias UPDATE FROM con la tabla #temp y usar las sentencias CASE o WHERE conditions.

Cuando se trabaja en una base de datos, intente perder la mentalidad de bucle, es un drenaje de rendimiento real, causará bloqueo / bloqueo y ralentizará el procesamiento. Si realiza un bucle en todas partes, su sistema no se escalará muy bien y será muy difícil acelerarlo cuando los usuarios comiencen a quejarse por la lentitud de las actualizaciones.

Publique el contenido de este procedimiento que desea llamar en un bucle, y apostaría 9 de cada 10 veces, podría escribirlo para trabajar en un conjunto de filas.