Ya no tienes que buscar más por todo internet ya que has llegado al espacio adecuado, poseemos la respuesta que buscas y sin liarte.
Solución:
Un cursor solo aceptará una declaración de selección, por lo que si el SQL realmente necesita ser dinámico, haga que el cursor de declaración forme parte de la declaración que está ejecutando. Para que lo siguiente funcione, su servidor tendrá que usar cursores globales.
Declare @UserID varchar(100)
declare @sqlstatement nvarchar(4000)
--move declare cursor into sql to be executed
set @sqlstatement = 'Declare users_cursor CURSOR FOR SELECT userId FROM users'
exec sp_executesql @sqlstatement
OPEN users_cursor
FETCH NEXT FROM users_cursor
INTO @UserId
WHILE @@FETCH_STATUS = 0
BEGIN
Print @UserID
EXEC asp_DoSomethingStoredProc @UserId
FETCH NEXT FROM users_cursor --have to fetch again within loop
INTO @UserId
END
CLOSE users_cursor
DEALLOCATE users_cursor
Si necesita evitar el uso de cursores globales, también puede insertar los resultados de su SQL dinámico en una tabla temporal y luego usar esa tabla para completar su cursor.
Declare @UserID varchar(100)
create table #users (UserID varchar(100))
declare @sqlstatement nvarchar(4000)
set @sqlstatement = 'Insert into #users (userID) SELECT userId FROM users'
exec(@sqlstatement)
declare users_cursor cursor for Select UserId from #Users
OPEN users_cursor
FETCH NEXT FROM users_cursor
INTO @UserId
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC asp_DoSomethingStoredProc @UserId
FETCH NEXT FROM users_cursor
INTO @UserId
END
CLOSE users_cursor
DEALLOCATE users_cursor
drop table #users
Este código es un muy buen ejemplo para una columna dinámica con un cursor, ya que no puede usar ‘+’ en @STATEMENT:
ALTER PROCEDURE dbo.spTEST
AS
SET NOCOUNT ON
DECLARE @query NVARCHAR(4000) = N'' --DATA FILTER
DECLARE @inputList NVARCHAR(4000) = ''
DECLARE @field sysname = '' --COLUMN NAME
DECLARE @my_cur CURSOR
EXECUTE SP_EXECUTESQL
N'SET @my_cur = CURSOR FAST_FORWARD FOR
SELECT
CASE @field
WHEN ''fn'' then fn
WHEN ''n_family_name'' then n_family_name
END
FROM
dbo.vCard
WHERE
CASE @field
WHEN ''fn'' then fn
WHEN ''n_family_name'' then n_family_name
END
LIKE ''%''[email protected]+''%'';
OPEN @my_cur;',
N'@field sysname, @query NVARCHAR(4000), @my_cur CURSOR OUTPUT',
@field = @field,
@query = @query,
@my_cur = @my_cur OUTPUT
FETCH NEXT FROM @my_cur INTO @inputList
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @inputList
FETCH NEXT FROM @my_cur INTO @inputList
END
RETURN
Trabajar con una base de datos no relacional (¿IDMS alguien?) a través de una conexión ODBC califica como uno de esos momentos en los que los cursores y el SQL dinámico parecen la única ruta.
select * from a where a=1 and b in (1,2)
tarda 45 minutos en responder mientras que se reescribe para usar conjuntos de claves sin la cláusula in se ejecutará en menos de 1 segundo:
select * from a where (a=1 and b=1)
union all
select * from a where (a=1 and b=2)
Si la declaración in para la columna B contiene 1145 filas, usar un cursor para crear declaraciones individuales y ejecutarlas como SQL dinámico es mucho más rápido que usar la cláusula in. tonto oye?
Y sí, no hay tiempo en una base de datos relacional en el que se deba usar el cursor. Simplemente no puedo creer que me he encontrado con una instancia en la que un bucle de cursor es varias magnitudes más rápido.
Comentarios y valoraciones del artículo
Agradecemos que desees estimular nuestra tarea exponiendo un comentario y dejando una puntuación te lo agradecemos.