Reputation: 90
I have a table of with a Unique ID and a set number of columns as seen below. Each row in the table has a UID and then distinct values in each column. The stored procedure takes each of these values (including the UID) and runs a multitude of other code.
To run this it would be:
EXEC stored_proc @UID @Col1 @Col2 etc
Each UID must run at a different time and each row for said UID needs to be loaded at the same time. Once loaded the script needs to move to the next UID.
The most obvious approach to this is via a cursor but I have had no real progress. I have attempted this via a cursor that uses a temporary table of only the UID and inner joined this for each row but sadly it did not work.
Sample table (actual table: circa 5000 rows):
UID | Version | Site | QuestionOI | GeneralAnswer |
---|---|---|---|---|
212109191425-01 | 6 | AGBNL | 4 | GENANSWER1 |
212109191425-01 | 6 | AGBNL | 9 | NULL |
212109191425-01 | 6 | AGBNL | 100 | NULL |
212109191425-01 | 6 | AGBNL | 103 | NULL |
212109191425-03 | 6 | AGFCA | 11 | NULL |
212109191425-03 | 6 | AGFCA | 22 | NULL |
212109191425-05 | 6 | COBAR | 4 | GENANSWER2 |
212109191425-05 | 6 | COBAR | 9 | NULL |
212109191425-05 | 6 | COBAR | 13 | NULL |
212109191425-05 | 6 | COBAR | 15 | NULL |
Can anyone think of an alternative approach/way to iteratively loop through each UID then run a stored procedure on each row for the UID? Use of a cursor is not essential.
Any help would be greatly appreciated and an award will be given for a clean and most importantly quick processing speed (note the nested SP takes little time to run)
Thanks!
Heres a sample of some code I tried as requested, it seemed to loop through each of the lines rather than UID then row. The stored procedure would run instead of the second print statement Note I've had to alter it a bit for sensitivity reasons.
Declare @ClientID VARCHAR;
Declare @UID VARCHAR;
DECLARE Cur1 CURSOR FOR
SELECT DISTINCT Site FROM #InsertTable
OPEN Cur1
FETCH NEXT FROM Cur1 INTO @ClientID;
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Processing ClientID: ' + @ClientID;
DECLARE Cur2 CURSOR FOR
SELECT UID FROM #InsertTable Where Site=@ClientID;
OPEN Cur2;
FETCH NEXT FROM Cur2 INTO @UID;
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Found UID: ' + Cast(@UID as Varchar);
FETCH NEXT FROM Cur2 INTO @UID;
END;
CLOSE Cur2;
DEALLOCATE Cur2;
FETCH NEXT FROM Cur1 INTO @ClientID;
END;
PRINT 'DONE';
CLOSE Cur1;
DEALLOCATE Cur1;
Upvotes: 0
Views: 3060
Reputation: 6550
A cursor would work and is the only way I know of to execute a procedure on each row individually. That said, it is not the most optimal approach. A cursor is almost always going to be slower than a set based approach. You might look into whether it could be refactored so you can avoid the cursor and row by row overhead.
DECLARE @YourCursor CURSOR
, @UID VARCHAR(50)
, @Version INT
, @Site VARCHAR(10)
, @QuestionOI INT
, @GeneralAnswer VARCHAR(10);
SET @YourCursor = CURSOR FOR
SELECT [UID]
, [Version]
, [Site]
, QuestionOI
, GeneralAnswer
FROM YourTable
ORDER BY [UID];
OPEN @YourCursor;
--- load first row
FETCH NEXT FROM @YourCursor
INTO @UID, @Version, @Site, @QuestionOI, @GeneralAnswer
WHILE @@FETCH_STATUS = 0
BEGIN
--- execute proc
EXEC stored_proc @UID, @Version, @Site, other variables...
--- get next row
FETCH NEXT FROM @YourCursor
INTO @UID, @Version, @Site, @QuestionOI, @GeneralAnswer
END;
CLOSE @YourCursor;
DEALLOCATE @YourCursor;
GO
Upvotes: 2