trigger stored hacer for sql-server tsql

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.


Necesita el Cursor de SQL Server.

Este es un enlace de MSDN . Refiere this para un simple ejemplo.


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 )