Cursors
Cursors
Database Programming
Introduction to Cursors
What is a CURSOR? Why do we need it?
In relational databases, operations are made on a
set of rows
For example
A SELECT statement returns a set of rows which is called a
result set.
A WHERE clause applies a filter for all row
3
Declaring a Cursor
Declaring a Cursor: basic syntax
DECLARE cursorName CURSOR
FOR select_statement
Declare Cursor
Declares a variable of a CURSOR type
The declaration includes:
The name of the cursor
The query used to build the result
Its scrolling behavior
Visibility of updates and deletes
4
Steps in using a Cursor
5
Steps in using a Cursor (cont.)
Step 1: Declare the cursor
Step 2: Open the cursor
Step 3: Step through the records row by row
The FETCH NEXT statement is used
@@FETCH_STATUS indicates the success of the FETCH
statement
@@FETCH_STATUS = 0 => record found
@@FETCH_STATUS = -1 => No record found
@@FETCH_STATUS = -2 => Deleted record
OPEN curEmployeeNames
WHILE @@FETCH_STATUS = 0
BEGIN
-- Do something with @Fname , @Lname
SELECT @Fname , @LName
CLOSE curEmployeeNames
DEALLOCATE curEmployeeNames
7
Nested Cursors
DECLARE curOuter CURSOR
FOR SELECT FirstName , LastName
FROM Employee
OPEN curOuter
FETCH NEXT FROM curOuter
INTO @Fname , @LName
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE curInner CURSOR
FOR SELECT C1 , C2 FROM TTTT
WHERE CX = @Fname
CLOSE curOuter
DEALLOCATE curOuter 8
Using Cursors - Example
Backup all user defined databases
DECLARE @fileName varchar(100)
DECLARE @dbName varchar(100)
9
Using Cursors - Example (cont.)
OPEN CurUserDatabases
FETCH NEXT FROM CurUserDatabases INTO @dbName
WHILE @@FETCH_STATUS = 0
BEGIN
SET @fileName = 'D:\My_Backup\’
+ CONVERT(varchar(50), GetDate())
+ @dbName + '.bak'
CLOSE CurUserDatabases 10
Example - Using table datatype
DECLARE @fileName varchar(100)
DECLARE @dbName varchar(100)
DECLARE @nbDatabases int
INSERT @tempTable
SELECT name
FROM master.dbo.sysDatabases
WHERE name NOT IN ('master','model','msdb','tempdb')
11
Example - Using table datatype (cont.)
SET @nbDatabases = @@ROWCOUNT
12
Example - Using TOP
DECLARE @cnt int = 1 --initialize iterator
DECLARE @rowCnt int --rowcount
DECLARE @sValue varchar(100)
DECLARE @mytbl TABLE (Value varchar(100))
IF @rowCnt > 0
BEGIN
print 'My Value is ' + @sValue
DELETE FROM @mytbl WHERE value = @sValue --processed
END
END 13
Cursors - Exercise
Use the cursor below to display the full name of the
employees along with the names of their Departments.
14
Summary – Defining a Cursor
Cursors use variables to store values returned in each
part of the loop.
You’ll need to DECLARE all variables you’ll need
DECLARE … CURSOR FOR SELECT
This where you’ll define the query for populating the cursor
OPEN the cursor and FETCH NEXT from the cursor
Use a WHILE loop (WHILE @@FETCH_STATUS = 0).
If a record is found, you’ll enter the loop BEGIN … END block
Statements inside the block will be executed
15
Summary – Defining a Cursor
16
Summary – When to use cursors
Mostly for database administration tasks like
Backups
rebuilding indexes
17
The FETCH Statement
NEXT
Returns the row immediately following the current row
If FETCH NEXT is the first fetch against a cursor, it returns the
first row in the result set
PRIOR
Returns the row immediately preceding the current row
If FETCH PRIOR is the first fetch against a cursor, no row is
returned and the cursor is left positioned before the first row.
FIRST : Returns the first row in the cursor and makes it
the current row.
LAST : Returns the last row in the cursor and makes it
the current row.
18
The FETCH Statement (cont.)
ABSOLUTE { n | @nvar}
If n or @nvar must be positive
Returns the row n rows from the front of the cursor
RELATIVE { n | @nvar}
If n or @nvar is positive, returns the row n rows beyond the
current row
If n or @nvar is negative, returns the row n rows prior to the
current row
19
Types of Cursors
SQL Server allows you to define four cursor types
These cursors vary in
their ability to detect changes in the base table and
in the resources they consume
20
Types of Cursors (cont.)
The four cursor types supported by SQL Server are:
Static cursors
Dynamic cursors
FAST_FORWARD cursors
Keyset-driven cursors
FORWARD_ONLY
Can only be scrolled from the first to the last row
FETCH NEXT is the only supported fetch option
SCROLL
all FETCH options are supported
22
Types of Cursors - STATIC
Defines a cursor that makes a temporary copy of the data
Displays the result set as it was when the cursor was opened
23
Types of Cursors - KEYSET
The membership and order of rows in the cursor are
fixed
The set of keys that uniquely identify the rows in the
cursor (keyset) is stored into a temporary table
Changes to non-key values in the base tables are visible
to the cursor
Inserts made by other users are not visible
24
Types of Cursors - DYNAMIC
All data changes made to the rows in its result set are
visible to the cursor
All UPDATE, INSERT, and DELETE statements made by all
users are visible through the cursor.
Data values, order, and membership of the rows can
change on each fetch
DYNAMIC SCROLL cursors support all the FETCH
options except ABSOLUTE
25
Types of Cursors - FAST_FORWARD
The default type of cursor
A FORWARD_ONLY, READ_ONLY cursor with
performance optimizations
FAST_FORWARD CAN NOT be specified if SCROLL is
also specified.
FAST_FORWARD cursors produce the least amount of
overhead on SQL Server
26
Types of Cursors - Example
Using scrollable cursors
DECLARE curEmployee CURSOR SCROLL
FOR SELECT FirstName FROM Employee
OPEN curEmployee
SELECT @FName
27
Types of Cursors - Example
DECLARE @EmpSalaryCursor as CURSOR;
OPEN @EmpSalaryCursor
28