web-dev-qa-db-fra.com

Comment puis-je parcourir un jeu d'enregistrements dans une procédure stockée?

Je dois parcourir un jeu d'enregistrements à partir d'une procédure stockée et exécuter une autre procédure stockée en utilisant chaque champ comme arguments. Je ne peux pas terminer cette itération dans le code. J'ai trouvé des échantillons sur les internets, mais ils semblent tous avoir affaire à un compteur. Je ne sais pas si mon problème impliquait un comptoir. J'ai besoin de l'équivalent T-SQL d'un foreach

Actuellement, ma première procédure stockée stocke son jeu d'enregistrements dans une table temporaire, #mytemp. Je suppose que j'appellerai la procédure stockée secondaire comme ceci:

while (something)
    execute nameofstoredprocedure arg1, arg2, arg3
end
17
David Fox

Vous devez créer un curseur pour parcourir le jeu d'enregistrements.

Exemple de tableau:

CREATE TABLE Customers
(
    CustomerId INT NOT NULL PRIMARY KEY IDENTITY(1,1)
    ,FirstName Varchar(50) 
    ,LastName VARCHAR(40)
)

INSERT INTO Customers VALUES('jane', 'doe')
INSERT INTO Customers VALUES('bob', 'smith')

Le curseur:

DECLARE @CustomerId INT, @FirstName VARCHAR(30), @LastName VARCHAR(50)

DECLARE @MessageOutput VARCHAR(100)

DECLARE Customer_Cursor CURSOR FOR 
    SELECT CustomerId, FirstName, LastName FROM Customers


OPEN Customer_Cursor 

FETCH NEXT FROM Customer_Cursor INTO
    @CustomerId, @FirstName, @LastName

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @MessageOutput = @FirstName + ' ' + @LastName



    RAISERROR(@MessageOutput,0,1) WITH NOWAIT

    FETCH NEXT FROM Customer_Cursor INTO
    @CustomerId, @FirstName, @LastName
END
CLOSE Customer_Cursor
DEALLOCATE Customer_Cursor

Voici un lien vers MSDN sur la façon de les créer.

http://msdn.Microsoft.com/en-us/library/ms180169.aspx

C'est pourquoi j'ai utilisé Raise Error au lieu de PRINT pour la sortie.
http://structuredsight.com/2014/11/24/wait-wait-dont-tell-me-on-second-thought/

29
kemiller2002

Eh bien, il est très facile de parcourir les lignes dans la procédure sql, il suffit d'utiliser le curseur, je vous donne un exemple ici, car il nous faut considérer un tableau Employé avec la colonne NOM et ÂGE contenant 50 enregistrements et vous devez exécuter une procédure stockée, dites TESTPROC qui prendra les paramètres de nom et d'âge de chaque ligne.

create procedure CursorProc
as
begin
   declare @count bigint;
   declare @age varchar(500)
   declare @name varchar(500)
   select @count = (select count(*) from employee)
   declare FirstCursor cursor for select name, age from employee
   open FirstCursor 
   while @count > 0
      begin
         fetch FirstCursor into @name, @age
         Exec TestProc @name, @age
         set @count = @count - 1
      end
   close FirstCursor 
   deallocate FirstCursor 
end

Assurez-vous de désallouer le curseur pour éviter les erreurs.

10
ahmar

essayez ceci (boucle libre du curseur):

CREATE TABLE #Results  (RowID  int identity(1,1), Col1  varchar(5), Col2 int, ... )
DECLARE @Current  int
       ,@End      int
DECLARE @Col1  varchar(5)
       ,@Col2 int
       ,...

--you need to capture the result set from the primary stored procedure
INSERT INTO #Results
    (Col1, COl2,...)
    EXEC nameofstoredprocedure_1 arg1, arg2, arg3
SELECT @End=@@ROWCOUNT,@Current=0

--process each row in the result set
WHILE @Current<@End
BEGIN
    SET @Current=@Current+1

    SELECT
        @Col1=COl1, @Col2=Col2
        FROM #Results
        WHERE RowID=@Current

    --call the secondary procedure for each row
    EXEC nameofstoredprocedure_2  @Col1, @Col2,...

END

exemple de travail:

CREATE PROCEDURE nameofstoredprocedure_1
(@arg1 int, @arg2 int, @arg3 int)
AS
SELECT 'AAA',@arg1 UNION SELECT 'BBB',@arg2 UNION SELECT 'CCC',@arg3
GO

CREATE PROCEDURE nameofstoredprocedure_2
(@P1 varchar(5), @P2 int)
AS
PRINT '>>'+ISNULL(@P1,'')+','+ISNULL(CONVERT(varchar(10),@P2),'')
GO

CREATE TABLE #Results  (RowID  int identity(1,1), Col1  varchar(5), Col2 int)
DECLARE @Current  int
       ,@End      int
DECLARE @Col1  varchar(5)
       ,@Col2 int


INSERT INTO #Results
    (Col1, COl2)
    EXEC nameofstoredprocedure_1 111, 222, 333
SELECT @End=@@ROWCOUNT,@Current=0

WHILE @Current<@End
BEGIN
    SET @Current=@Current+1

    SELECT
        @Col1=COl1, @Col2=Col2
        FROM #Results
        WHERE RowID=@Current

    EXEC nameofstoredprocedure_2  @Col1, @Col2

END

PRODUCTION:

(3 row(s) affected)
>>AAA,111
>>BBB,222
>>CCC,333
8
KM.