2010-04-12 37 views
14

Tôi cần phải lặp qua một recordset từ một thủ tục lưu sẵn và thực hiện một thủ tục được lưu trữ khác bằng cách sử dụng từng trường làm đối số. Tôi không thể hoàn tất việc lặp lại này trong mã. Tôi đã tìm thấy mẫu trên internets, nhưng tất cả họ dường như đối phó với một truy cập. Tôi không chắc chắn nếu vấn đề của tôi liên quan đến một truy cập. Tôi cần tương đương T-SQL là foreachLàm thế nào tôi có thể lặp qua một recordset trong một thủ tục lưu sẵn?

Hiện tại, thủ tục lưu trữ đầu tiên của tôi lưu trữ bản ghi trong bảng tạm thời, #mytemp. Tôi cho rằng tôi sẽ gọi thủ tục được lưu trữ phụ như sau:

while (something) 
    execute nameofstoredprocedure arg1, arg2, arg3 
end 

Trả lời

16

Bạn cần tạo con trỏ để lặp qua tập bản ghi.

Ví dụ Bảng:

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') 

Cursor:

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 

Dưới đây là một liên kết đến MSDN về cách tạo ra chúng.

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

Đây là lý do tại sao tôi đã sử dụng Lỗi Raise thay vì PRINT cho đầu ra.
http://structuredsight.com/2014/11/24/wait-wait-dont-tell-me-on-second-thought/

+0

Tôi có thể chuyển liên kết eggheadcafe.com sang mã của mình. thanks –

+0

Bài báo egghead đã làm được điều đó! – PhilNicholas

+0

Câu trả lời này đã bị gắn cờ để xóa vì đó là câu trả lời chỉ liên kết có liên kết bị hỏng. Bạn có thể vui lòng mở rộng câu trả lời để giải quyết đầy đủ câu hỏi mà không yêu cầu người đọc nhấp qua liên kết không? – josliber

5

thử này (con trỏ vòng lặp miễn phí):

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 @[email protected]@ROWCOUNT,@Current=0 

--process each row in the result set 
WHILE @Current<@End 
BEGIN 
    SET @[email protected]+1 

    SELECT 
     @Col1=COl1, @Col2=Col2 
     FROM #Results 
     WHERE [email protected] 

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

END 

dụ làm việc:

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 @[email protected]@ROWCOUNT,@Current=0 

WHILE @Current<@End 
BEGIN 
    SET @[email protected]+1 

    SELECT 
     @Col1=COl1, @Col2=Col2 
     FROM #Results 
     WHERE [email protected] 

    EXEC nameofstoredprocedure_2 @Col1, @Col2 

END 

OUTPUT:

(3 row(s) affected) 
>>AAA,111 
>>BBB,222 
>>CCC,333 
+0

khi tôi đã thử điều này với mã của tôi, vòng lặp không bao giờ được thực hiện với 21 bản ghi trong #mytemp –

+0

Nó hoạt động cho tôi. giữa 'SELECT @End = @@ ROWCOUNT, @ Current = 0' và' WHILE @Current <@ End' thêm điều này: 'print 'sẽ xử lý' + ISNULL (CONVERT (varchar (5), @ End), '') + 'rows'' và giữa 'SET @ Current = @ Current + 1' và' SELECT ...'thêm dòng này:' print 'row xử lý' + ISNULL (CONVERT (varchar (5), @ Current), '') 'Ngoài ra, nếu bạn KHÔNG điền #Results với chèn và chạy WHILE cùng một lúc bạn có thể thêm điều này, trước khi: 'SELECT @ End = COUNT (*) TỪ # Kết quả ' –

+0

con trỏ xấu, đăng sửa đổi câu trả lời của tôi và tôi sẽ chỉ ra lỗi của bạn. Tôi thà thò mắt ra trước khi dùng con trỏ. –

11

Vâng nó rất dễ dàng để lặp qua các hàng trong thủ tục sql u chỉ cần sử dụng con trỏ, tôi là givin g cho bạn một ví dụ ở đây, vì chúng ta hãy xem xét một bảng nhân viên với cột TÊNTUỔI với 50 hồ sơ vào nó và u có để thực hiện một thủ tục lưu trữ nói TESTPROC mà sẽ lấy tên và tuổi tham số của từng hàng.

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 

Đảm bảo bạn deallocate con trỏ để tránh lỗi.

+0

bạn đã lưu ngày của tôi. Thủ tục lưu trữ đầu tiên của tôi bao giờ :) – rajugaadu

Các vấn đề liên quan