Reputation: 53
How Can I Skip a row(an iteration) in MSSQL Cursor based on some condition, I have a DTS which migrates thousands of records and based on some criteria, some records need not be migrated as they are duplicates and want to skip these records.
Any idea how I can accomplish this in MSSQL Cursor?
Upvotes: 4
Views: 16365
Reputation: 41
WHILE(@@FETCH_STATUS = 0)
BEGIN
FETCH NEXT FROM CURSOR INTO @PARAM
IF @cond CONTINUE /* Skip */
/* Do stuff */
END
Use a Label: and a GOTO to continue execution from another place in the code
BEGIN
FETCH NEXT FROM CURSOR INTO @PARAM
IF @cond GOTO: endOfCursorLabel
/* Do stuff */
endOfCursorLabel:
END
Reference "Control-of-Flow" for more info https://learn.microsoft.com/en-us/sql/t-sql/language-elements/control-of-flow?view=sql-server-ver16
Upvotes: 0
Reputation: 41
I know that it I am too late to answer this question but for future seekers.. I believe the correct way to handle this is described in MSDN
your code is using a WHILE Loop (WHILE @@FETCH_STATUS = 0)
To properly exit a while loop you use the BREAK key word
To skip an iteration in your loop you use the CONTINUE keyword
FROM MSDN:
BREAK Causes an exit from the innermost WHILE loop. Any statements that appear after the END keyword, marking the end of the loop, are executed.
CONTINUE Causes the WHILE loop to restart, ignoring any statements after the CONTINUE keyword.
EXAMPLE: -- AFTER declaring and opening a cursor...
FETCH NEXT FROM Curs INTO @ID
WHILE @@FETCH_STATUS = 0
BEGIN
-- do something
IF [condition to skip record]
CONTINUE
FETCH NEXT FROM Curs INTO @ID
END
Upvotes: 4
Reputation: 14677
I know it's too late to answer this question. But for the sake of other users seeking for a better answer. You can simply skip the record by calling the FETCH NEXT
.
WHILE @@FETCH_STATUS = 0
IF @ParameterName = '@RETURN_VALUE'
FETCH NEXT FROM @procSchema INTO @ParameterName, @Type;
.... Rest of the logic goes here
With this approach you don't have to wrap the whole logic in a If statement instead you'll move to the next one record skipping the current record.
Upvotes: 1
Reputation: 36
I'm making a few assumptions here but you could use the following as a guide:
-- create some test data
SELECT ' ' [Word] INTO #MyTempDataset;
INSERT INTO #MyTempDataset SELECT 'This';
INSERT INTO #MyTempDataset SELECT 'is';
INSERT INTO #MyTempDataset SELECT 'a';
INSERT INTO #MyTempDataset SELECT 'basic';
INSERT INTO #MyTempDataset SELECT 'basic';
INSERT INTO #MyTempDataset SELECT 'test';
DECLARE @counter INT
DECLARE @word VARCHAR(50)
DECLARE myCursor CURSOR
FOR SELECT *
FROM #MyTempDataset;
OPEN myCursor
FETCH NEXT FROM myCursor INTO @word
WHILE @@FETCH_STATUS = 0
BEGIN
-- check for condition
SELECT @counter = Count(*)
FROM #MyTempDataset
WHERE word = @word
IF @counter =1
BEGIN
-- process the unique records
PRINT @word
END
FETCH NEXT FROM myCursor INTO @word
END
CLOSE myCursor;
DEALLOCATE myCursor;
DROP TABLE #MyTempDataset;
Upvotes: 2
Reputation: 1873
I guess the simplest way is to write IF statement inside the cursor. If the condition will be false you will skip records.
DECLARE @ID INT
DECLARE Curs CURSOR FAST_FORWARD
DECLARE @Cnt INT
CREATE TABLE ##Duplicates (ID INT, CarColor VARCHAR (50) )
FOR
SELECT DISTINCT CarID
FROM dbo.CarPark
WHERE CarColour <> 'red'
ORDER BY CarID
OPEN Curs
FETCH NEXT FROM Curs INTO @ID
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO ##Duplicates
SELECT CarID, CarColor
FROM dbo.CarPark
WHERE ID = @ID;
SET @Cnt = (SELECT Count(*) FROM ##Duplicates WHERE ID = @ID) ;
IF @Cnt < 2
THEN /* Migrate */
ELSE PRINT 'Duplicate'
END
FETCH NEXT FROM Curs INTO @ID
END
CLOSE Curs
DEALLOCATE Curs;
Upvotes: 4