SQL Server Cursor Types - KEYSET Cursor | SQL Server Tutorial / TSQL Tutorial

When we open Keyset Cursor the membership and order of rows in the cursor is fixed. KeySet Cursor create a temp table in TempDB with uniquely built values from the columns which we use in Select statement.

Here are important points to remember about KEYSET Cursor in SQL Server


  • If your Select query is using any table without Unique Index, the KEYSET cursor is simply going to be converted to Static Cursor. Make sure all of the tables you are using in Select Query has unique index. This is important as KEYSET Cursor build unique identifiers for the rows by using these unique values.
  • If we insert the rows in source table/s once the cursor is open. Those Inserts will not be visible in already opened cursor.
  • If we make update to nonkey values in the base tables, those changes will be visible in cursor.
  • If you update the Key column value in Base Table/s while the cursor is opened and then try to fetch the value. @@FETCH_STATUS will return you -2. The updated made inside the cursor to Key Column with WHERE CURRENT OF clause will be visible at the end of Cursor.
  • If you delete the row from Base Table/s while the cursor is open and then try to fetch that row in cursor, @@FETCH_STATUS will return -2.
  • KEYSET cursors are scrollable.
It is hard to put the snapshots together with all the details here. I would suggest you watch the video to see how KEYSET options work in real.


Create table dbo.Customer ( 
CustomerId Int ,
CustomerName VARCHAR(100),
StreetAddress VARCHAr(100),
City VARCHAR(100),
State CHAR(2))
go

--Create Unique Index on CustomerID

CREATE UNIQUE INDEX UQ_CustomerID
   ON dbo.Customer (CustomerID); 

--Insert few Records in Sample Table
Insert into dbo.Customer
Select 1,'Aamir shahzad','Test Street Address','Charlotte','NC'
Union all
Select 2,'M Raza','Test Street Address','Charlotte','NC'
union all
Select 3,'John Smith','Test Street Address','New York City','NY'
union All
Select 4,'Christy Richard','Test Street Address','Rio Rancho','NM'

--Insert NEW Record
Insert into dbo.Customer
Select 5,'Robert Ladson','Pathway Street Address','High Point','NC'

--Delete Records
Delete from dbo.Customer
Where CustomerID in (3,4)

--Update All Record for NONKEY Column
Update dbo.Customer
set CustomerName='NO NAME'

--Update Key Column value
Update dbo.customer
set CustomerID=9
where Customerid=3





--KEYSET CURSOR Script
Declare @CustomerID INT
Declare @CustomerNAme VARCHAR (100)
DECLARE @StreetAddress VARCHAR(100)
DECLARE @City VARCHAR(100)
DECLARE @State CHAR(2)

--DECLARE A CURSOR
DECLARE CUR CURSOR
KEYSET
FOR
Select CustomerID,CustomerName,StreetAddress,City,State from dbo.Customer

--OPEN CURSOR
OPEN CUR
Print 'CURSOR IS OPEN'
--FETCH NEXT RECORD
FETCH NEXT FROM CUR INTO @CustomerID,@CustomerNAme,@StreetAddress,@City,@State
WHILE @@FETCH_STATUS=0
BEGIN 
RAISERROR ('',0,1) WITH NOWAIT
WAITFOR DELAY '00:00:15'
--You can use CONCAT Function in SQL 2012 AND Latest for Contatenation of Integters and Strings
--PRINT CONCAT(@CustomerID,' ',@CustomerNAme,' ',@StreetAddress,' ',@City,' ',@State) 
Print CAST(@CustomerID AS VARCHAR(10))+' '+@CustomerNAme+' '+@StreetAddress+' '+@City+' '+@State 
FETCH NEXT FROM CUR INTO @CustomerID,@CustomerNAme,@StreetAddress,@City,@State
Print @@FETCH_STATUS
END
CLOSE CUR
DEALLOCATE CUR




Video Demo: What are KEYSET Cursors in SQL Server and How KEYSET Cursor works