SQL Server Cursors: How They Work and a Complete T-SQL Example

A cursor provides row-by-row navigation through a query result. It is helpful when a task genuinely needs sequential procedural work, but should not replace set-based SQL without a reason.

Cursor lifecycle

A typical T-SQL cursor is declared, opened, fetched, used in a loop, closed, and deallocated. Options such as LOCAL, FAST_FORWARD, and READ_ONLY affect cursor scope and behaviour.

Working example

DECLARE @CustomerID int;
DECLARE customer_cursor CURSOR LOCAL FAST_FORWARD FOR
  SELECT CustomerID FROM dbo.Customers WHERE IsActive = 1;
OPEN customer_cursor;
FETCH NEXT FROM customer_cursor INTO @CustomerID;
WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT CONCAT('Customer: ', @CustomerID);
    FETCH NEXT FROM customer_cursor INTO @CustomerID;
END;
CLOSE customer_cursor;
DEALLOCATE customer_cursor;

Compare a set-based approach

If the objective is to update every active customer’s status, a single UPDATE with a WHERE clause normally expresses the intention more simply and can avoid cursor overhead.

Error handling

For production procedures, ensure cleanup also occurs when work fails. Limit long transactions and test behaviour with large result sets.


AI disclosure and reuse: This AI-generated article is rewritten from an existing Open Education post (ID 69249). Additional explanations, code examples, and version notes may have been added. You may reuse the newly generated article text with or without attribution. Third-party trademarks and linked works retain their own rights. AI can make mistakes. Check examples, permissions, supported SQL Server versions, and documentation before use in any live system.

Leave a Reply