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
¿Es la declaración y el uso de un cursor mi única opción si quiero iterar a través de las filas? ¿Hay otra manera?
En primer lugar, debe estar absolutamente seguro de que necesita iterar a través de cada fila - las operaciones basadas en conjuntos serán más rápidas en todos los casos que se me ocurren y normalmente utilizarán un código más sencillo.
Dependiendo de sus datos, puede ser posible hacer un bucle utilizando sólo sentencias select como se muestra a continuación:
Declare @Id int
While (Select Count(*) From ATable Where Processed = 0) > 0
Begin
Select Top 1 @Id = Id From ATable Where Processed = 0
--Do some processing here
Update ATable Set Processed = 1 Where Id = @Id
End
Otra alternativa es utilizar una tabla temporal:
Select *
Into #Temp
From ATable
Declare @Id int
While (Select Count(*) From #Temp) > 0
Begin
Select Top 1 @Id = Id From #Temp
--Do some processing here
Delete #Temp Where Id = @Id
End
La opción que debe elegir depende realmente de la estructura y el volumen de sus datos.
Nota: Si usted está usando SQL Server que sería mejor usar:
WHILE EXISTS(SELECT * FROM #Temp)
Usando COUNT
tendrás que tocar todas las filas de la tabla, el EXISTS
sólo necesita tocar la primera (ver la respuesta de Josef's más abajo).
Así es como yo lo haría:
Select Identity(int, 1,1) AS PK, DatabaseID
Into #T
From @databases
Declare @maxPK int;Select @maxPK = MAX(PK) From #T
Declare @pk int;Set @pk = 1
While @pk <= @maxPK
Begin
-- Get one record
Select DatabaseID, Name, Server
From @databases
Where DatabaseID = (Select DatabaseID From #T Where PK = @pk)
--Do some processing here
--
Select @pk = @pk + 1
End
[Editar] Debido a que probablemente me saltó la palabra "variable" cuando leí la pregunta por primera vez, aquí está una respuesta actualizada...
declare @databases table
(
PK int IDENTITY(1,1),
DatabaseID int,
Name varchar(15),
Server varchar(15)
)
-- insert a bunch rows into @databases
--/*
INSERT INTO @databases (DatabaseID, Name, Server) SELECT 1,'MainDB', 'MyServer'
INSERT INTO @databases (DatabaseID, Name, Server) SELECT 1,'MyDB', 'MyServer2'
--*/
Declare @maxPK int;Select @maxPK = MAX(PK) From @databases
Declare @pk int;Set @pk = 1
While @pk <= @maxPK
Begin
/* Get one record (you can read the values into some variables) */
Select DatabaseID, Name, Server
From @databases
Where PK = @pk
/* Do some processing here */
/* ... */
Select @pk = @pk + 1
End