A Very Basic SQL Cursor for SQL Server (T-SQL)

Here’s a quick overview video of how to write and use a basic cursor in SQL Server’s T-SQL. The SQL code for both a regular SELECT cursor as well as an UPDATE cursor is below.

Cursors are really useful if you want to perform a specific action on all of the rows in a particular database table. They are especially well suited to task-based rather than set-based processes that have to call an external function or resource on each row, for example calling a component to add data to a messaging queue or send an email.

The downside to cursors is that their performance can be slow, so it’s best to avoid using them on very large tables or when query performance is important.

Cursors used to be one of the only ways of performing certain actions on every row in a table. However, be aware that there are alternatives, such as using a WHILE EXISTS loop or the more recent T-SQL Common Table Expressions (CTE).

Incidentally, in both examples I use the SQL Server Northwind sample database. Here’s a video that shows you how to install this really useful test database in SQL Server Management Studio:

Basic SQL Cursor for a SELECT Statement

DECLARE @ProductName NVARCHAR(40)
DECLARE @DiscontinuedProducts NVARCHAR(4000)

SET @DiscontinuedProducts = ‘Discontinued Products…’

DECLARE mycursor CURSOR FOR
SELECT productname
FROM   products
WHERE  discontinued = 1

OPEN mycursor

FETCH next FROM mycursor INTO @ProductName

WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @DiscontinuedProducts = @DiscontinuedProducts + @ProductName + ‘,’

FETCH next FROM mycursor INTO @ProductName
END

CLOSE mycursor
DEALLOCATE mycursor

Basic SQL Cursor with Table UPDATE

DECLARE @ProductID INT
DECLARE @Discontinued BIT
DECLARE @UnitsInStock SMALLINT

SET nocount ON

DECLARE mycursor CURSOR FOR
SELECT productid,
unitsinstock,
discontinued
FROM   products

OPEN mycursor
FETCH next FROM mycursor INTO @ProductID, @UnitsInStock, @Discontinued

WHILE @@FETCH_STATUS = 0
BEGIN
IF @Discontinued = 1
BEGIN
UPDATE products
SET    productstatus = ‘DISCONTINUED’
WHERE  productid = @ProductID
END
ELSE
BEGIN
IF @UnitsInStock > 0
BEGIN
UPDATE products
SET    productstatus = ‘IN STOCK’
WHERE  productid = @ProductID
END
ELSE
BEGIN
UPDATE products
SET    productstatus = ‘OUT OF STOCK’
WHERE  productid = @ProductID
END
END

FETCH next FROM mycursor INTO @ProductID, @UnitsInStock, @Discontinued
END

CLOSE mycursor

DEALLOCATE mycursor
–SELECT * FROM Products

Leave a Reply

Your email address will not be published. Required fields are marked *