How do you use a cursor to update rows in a table based on a condition?
Posted by DavidLee
Last Updated: July 22, 2024
Using a cursor to update rows in a table based on a condition involves a few steps. Cursors allow you to iterate through individual rows of a result set, which can be beneficial when you need to perform complex updates that can't be done with a single SQL statement. Here's a step-by-step guide on how to use a cursor to accomplish this in SQL Server, though the concept is similar in other relational database management systems.
Step 1: Declare the Cursor
First, you'll need to declare a cursor and define the SQL query that will return the rows you want to update.
DECLARE @id INT, @newValue VARCHAR(50);
DECLARE cursor_name CURSOR FOR
SELECT id, column_to_update -- SELECT the necessary columns
FROM your_table
WHERE condition; -- Add your filter condition here
Step 2: Open the Cursor
After declaring the cursor, open it to make it available for fetching rows.
OPEN cursor_name;
Step 3: Fetch Rows
You'll then fetch the rows one by one from the cursor into the declared variables.
FETCH NEXT FROM cursor_name INTO @id, @newValue;
Step 4: Loop Through the Cursor
You need to process each fetched row using a loop. This is typically done using a WHILE loop.
WHILE @@FETCH_STATUS = 0
BEGIN
    -- Update the rows based on the fetched data
    UPDATE your_table
    SET column_to_update = 'new_value' -- or use @newValue
    WHERE id = @id; -- Condition to identify the row to update

    -- Fetch the next row
    FETCH NEXT FROM cursor_name INTO @id, @newValue;
END;
Step 5: Clean Up
After finishing the updates, close and deallocate the cursor to free up system resources.
CLOSE cursor_name;
DEALLOCATE cursor_name;
Example
Here’s a complete example that updates the status column of all rows where status is 'Pending' to 'Completed'.
DECLARE @id INT, @status VARCHAR(50);

DECLARE update_cursor CURSOR FOR
SELECT id, status
FROM orders
WHERE status = 'Pending';

OPEN update_cursor;

FETCH NEXT FROM update_cursor INTO @id, @status;

WHILE @@FETCH_STATUS = 0
BEGIN
    UPDATE orders
    SET status = 'Completed'
    WHERE id = @id;

    FETCH NEXT FROM update_cursor INTO @id, @status;
END;

CLOSE update_cursor;
DEALLOCATE update_cursor;
Important Note
Cursors can be resource-intensive and are generally slower than using set-based operations. Whenever possible, try to use set-based SQL updates rather than cursors. For example, the above update can be performed without a cursor as follows:
UPDATE orders
SET status = 'Completed'
WHERE status = 'Pending';
Using set-based operations is usually more efficient and is the preferred approach in SQL. Use cursors only when necessary and when you cannot achieve the same result with a simple update statement.
Related Content