0% found this document useful (0 votes)
10 views

Cursors

Uploaded by

Kalid Abdu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views

Cursors

Uploaded by

Kalid Abdu
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 28

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

 Sometimes our application logic needs to work with

one row at a time rather than the entire


result set at once.
 This can be done using cursors.
2
Cursor
 A CURSOR is a pointer-like data type (a handle) that
allows you access a result-set one row at a time
 It is a pointer that will walk through the record set row by row
 A cursor is used to perform some action on each row of
a result set one row at a time
 SQL Server works faster with data as a set than it does
with interactive series of commands

 Cursors are slower and consume more resources


 They should be used as the last option

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

 Step 4: Close the cursor


 Releases the current result set associated with the cursor
 The cursor can be opened again after it is closed

 Step 5: Deallocate (release memory): releases the


resources used by the cursor 6
Example - Using Cursors
DECLARE curEmployeeNames CURSOR
FOR SELECT FirstName , LastName
FROM Employee

OPEN curEmployeeNames

FETCH NEXT FROM curEmployeeNames


INTO @Fname , @LName

WHILE @@FETCH_STATUS = 0
BEGIN
-- Do something with @Fname , @Lname
SELECT @Fname , @LName

FETCH NEXT FROM curEmployeeNames


INTO @Fname , @LName
END

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

-- Open the INNER cursor


-- scroll through the rows of the INNER cursor and do something with C1 , C2
-- Close and deallocate INNER cursor

FETCH NEXT FROM curOuter


INTO @Fname , @LName
END

CLOSE curOuter
DEALLOCATE curOuter 8
Using Cursors - Example
 Backup all user defined databases
DECLARE @fileName varchar(100)
DECLARE @dbName varchar(100)

DECLARE CurUserDatabases CURSOR


FOR
SELECT name
FROM master.dbo.sysDatabases
WHERE name NOT IN ('master','model','msdb','tempdb')

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'

BACKUP DATABASE @dbName TO DISK = @filename

FETCH NEXT FROM CurUserDatabases INTO @dbName


END

CLOSE CurUserDatabases 10
Example - Using table datatype
DECLARE @fileName varchar(100)
DECLARE @dbName varchar(100)
DECLARE @nbDatabases int

SET @fileName = 'D:\My_Backup\' + CONVERT(varchar(50),


GetDate()) + '.bak’

DECLARE @tempTable TABLE


(rowID int IDENTITY , name sysname)

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

WHILE ( @nbDatabases > 0)


BEGIN
SELECT @dbName =
( SELECT name FROM @tempTable
WHERE rowID = @nbDatabases )

BACKUP DATABASE @dbName TO DISK = @filename

SET @nbDatabases = @nbDatabases - 1


END

12
Example - Using TOP
DECLARE @cnt int = 1 --initialize iterator
DECLARE @rowCnt int --rowcount
DECLARE @sValue varchar(100)
DECLARE @mytbl TABLE (Value varchar(100))

INSERT into @mytbl(Value) SELECT name FROM master..sysdatabases

SET @rowCnt = @@ROWCOUNT

WHILE @rowCnt > 0


BEGIN
SELECT TOP 1 @sValue = Value from @mytbl
SET @rowCnt = @@ROWCOUNT --ensure that we still have data

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.

DECLARE CurEmployees CURSOR


FOR
SELECT FName, LName, DepID
FROM Employee

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

 After you’ve looped through the whole result set


 You should CLOSE the cursor and DEALLOCATE it.

15
Summary – Defining a Cursor

16
Summary – When to use cursors
 Mostly for database administration tasks like
 Backups
 rebuilding indexes

 For one-time tasks


 Only when you’re sure that possible poor performance won’t
impact the overall system performance
 Calling a stored procedure a few times using different
parameters.
 In that case, you would get parameters from cursor variables and
make calls inside the loop

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

 A cursor can detect changes to rows only when it


attempts to fetch those rows a second time.

20
Types of Cursors (cont.)
 The four cursor types supported by SQL Server are:
 Static cursors
 Dynamic cursors
 FAST_FORWARD cursors
 Keyset-driven cursors

 Static cursors detect no changes, and consume


relatively few resources while scrolling.
 Dynamic cursors detect all changes, but consume more
resources while scrolling.
 FAST_FORWARD cursors are READ_ONLY cursors
with performance optimizations enabled
 Keyset-driven cursors lie in between
 They detect most changes, but with less resource demands than
21
dynamic cursors
Declare Cursors - Syntax
 Declaring a Cursor
DECLARE cursor_name CURSOR
[ FORWARD_ONLY | SCROLL ]
[ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
FOR select_statement

 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

 Modifications made by other uses are not seen by the


cursor
 Does not display new rows inserted in the database after
the cursor was opened
 No UPDATE, INSERT, or DELETE operations are reflected in a
static cursor unless the cursor is closed and reopened
 Consume relatively few resources while scrolling

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

FETCH FIRST FROM curEmployee INTO @FName


FETCH LAST FROM curEmployee INTO @FName
FETCH ABSOLUTE 2 FROM curEmployee INTO @FName
FETCH RELATIVE -2 FROM curEmployee INTO @FName

SELECT @FName

27
Types of Cursors - Example
DECLARE @EmpSalaryCursor as CURSOR;

SET @EmpSalaryCursor = CURSOR FORWARD_ONLY


FOR
SELECT FName, LName, Salary
FROM Employee

OPEN @EmpSalaryCursor

28

You might also like