sql-server - stored - select foreach sql server
¿Cómo escribir un foreach en SQL Server? (8)
Estoy tratando de lograr algo en la línea de un para-cada, donde me gustaría tomar los Id. De una declaración seleccionada devuelta y usar cada uno de ellos.
DECLARE @i int
DECLARE @PractitionerId int
DECLARE @numrows int
DECLARE @Practitioner TABLE (
idx smallint Primary Key IDENTITY(1,1)
, PractitionerId int
)
INSERT @Practitioner
SELECT distinct PractitionerId FROM Practitioner
SET @i = 1
SET @numrows = (SELECT COUNT(*) FROM Practitioner)
IF @numrows > 0
WHILE (@i <= (SELECT MAX(idx) FROM Practitioner))
BEGIN
SET @PractitionerId = (SELECT PractitionerId FROM @Practitioner WHERE idx = @i)
--Do something with Id here
PRINT @PractitionerId
SET @i = @i + 1
END
Por el momento tengo algo que se parece al anterior, pero estoy recibiendo el error:
Nombre de columna inválido ''idx''.
Alguien podria
Aunque los cursores suelen considerar un mal horrible, creo que este es un caso para el cursor FAST_FORWARD, lo más parecido que se puede obtener a FOREACH en TSQL.
La siguiente línea es incorrecta en su versión:
WHILE (@i <= (SELECT MAX(idx) FROM @Practitioner))
(Falta el @)
Podría ser una idea cambiar tu convención de nombres para que las tablas sean más diferentes.
Parece que quieres usar un CURSOR
. Aunque la mayoría de las veces es mejor utilizar una solución basada en conjuntos, hay algunas veces en que un CURSOR
es la mejor solución. Sin saber más acerca de su problema real, no podemos ayudarlo más que eso:
DECLARE @PractitionerId int
DECLARE MY_CURSOR CURSOR
LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR
SELECT DISTINCT PractitionerId
FROM Practitioner
OPEN MY_CURSOR
FETCH NEXT FROM MY_CURSOR INTO @PractitionerId
WHILE @@FETCH_STATUS = 0
BEGIN
--Do something with Id here
PRINT @PractitionerId
FETCH NEXT FROM MY_CURSOR INTO @PractitionerId
END
CLOSE MY_CURSOR
DEALLOCATE MY_CURSOR
Se me ocurrió una manera muy efectiva, (creo) legible de hacer esto.
1. create a temp table and put the records you want to iterate in there
2. use WHILE @@ROWCOUNT <> 0 to do the iterating
3. to get one row at a time do, SELECT TOP 1 <fieldnames>
b. save the unique ID for that row in a variable
4. Do Stuff, then delete the row from the temp table based on the ID saved at step 3b.
Aquí está el código. Lo siento, está usando mis nombres de variables en lugar de los que están en la pregunta.
declare @tempPFRunStops TABLE (ProformaRunStopsID int,ProformaRunMasterID int, CompanyLocationID int, StopSequence int );
INSERT @tempPFRunStops (ProformaRunStopsID,ProformaRunMasterID, CompanyLocationID, StopSequence)
SELECT ProformaRunStopsID, ProformaRunMasterID, CompanyLocationID, StopSequence from ProformaRunStops
WHERE ProformaRunMasterID IN ( SELECT ProformaRunMasterID FROM ProformaRunMaster WHERE ProformaId = 15 )
-- SELECT * FROM @tempPFRunStops
WHILE @@ROWCOUNT <> 0 -- << I dont know how this works
BEGIN
SELECT TOP 1 * FROM @tempPFRunStops
-- I could have put the unique ID into a variable here
SELECT ''Ha'' -- Do Stuff
DELETE @tempPFRunStops WHERE ProformaRunStopsID = (SELECT TOP 1 ProformaRunStopsID FROM @tempPFRunStops)
END
Su recuento de selección y selección máxima debe ser de la variable de tabla en lugar de la tabla real
DECLARE @i int
DECLARE @PractitionerId int
DECLARE @numrows int
DECLARE @Practitioner TABLE (
idx smallint Primary Key IDENTITY(1,1)
, PractitionerId int
)
INSERT @Practitioner
SELECT distinct PractitionerId FROM Practitioner
SET @i = 1
SET @numrows = (SELECT COUNT(*) FROM @Practitioner)
IF @numrows > 0
WHILE (@i <= (SELECT MAX(idx) FROM @Practitioner))
BEGIN
SET @PractitionerId = (SELECT PractitionerId FROM @Practitioner WHERE idx = @i)
--Do something with Id here
PRINT @PractitionerId
SET @i = @i + 1
END
Supongamos que la columna PractitionerId es única, luego puede usar el siguiente ciclo
DECLARE @PractitionerId int = 0
WHILE(1 = 1)
BEGIN
SELECT @PractitionerId = MIN(PractitionerId)
FROM dbo.Practitioner WHERE PractitionerId > @PractitionerId
IF @PractitionerId IS NULL BREAK
SELECT @PractitionerId
END
Yo diría que probablemente todo funcione, excepto que la columna idx
no existe en realidad en la tabla que está seleccionando. Tal vez quiso seleccionar de @Practitioner
:
WHILE (@i <= (SELECT MAX(idx) FROM @Practitioner))
porque eso está definido en el código anterior así:
DECLARE @Practitioner TABLE (
idx smallint Primary Key IDENTITY(1,1)
, PractitionerId int
)