You are on page 1of 23

SQL Server : S dng bin kiu d liu Cursor

Phn ln cc c s d liu quan h thng lm vic trn d liu ca nhiu dng mu tin, cn gi l mt b cc mu tin. V d lnh SELECT kt qu lun tr v nhiu dng d liu hn l mt dng d liu. Ngc li i vi mt s ngn ng lp trnh hoc bn trong cc ng dng th ngi lp trnh vn cn cc thi quen x l v tnh ton d liu trn tng dng ring l. p ng c yu cu ny ca cc ngi lp trnh, mun lm vic ch trn tng dng d liu ti thi im hin hnh, Microsoft SQL Server to ra mt kiu d liu chnh l kiu cursor. 1/- Khi nim v cursor : Bn c th hnh dung kiu d liu cursor (kiu con tr) ging nh mt cun s danh b cha thng tin lin lc ca cc khch hng giao dch trong mt cng ty. Bng cch d tm th cng, bn s phi s dng n mt v tay tham chiu n tn ca cc khch hng bt b trong s danh b . Bn c th di chuyn ln, xung hoc qua trang tm ra cc khch hng mong mun, nhng ti thi im hin hnh tay v mt ca bn ch ng ti mt khch hng m thi. Hot ng ca kiu d liu cursor trong Transaction-SQL hon ton ging nh v d minh ha trn. Tuy nhin, cursor c nhiu kiu khc nhau cho php bn c th chn la nh ngha theo ng yu cu m mnh mong mun. Ty thuc vo kiu cursor nh ngha m vic c v cp nht d liu s c hiu lc nh th no.

So snh c ch cursor v b cc mu tin 2/- Cc bc s dng kiu d liu cursor :

i vi cc kiu d liu thng thng sau khi khai bo bin cng vi kiu d liu thch hp, bn s c php gn gi tr cn lu tr vo bn trong bin. Hot ng ca bin kiu d liu cursor hon ton khng n gin nh th, s dng c bin kiu d liu cursor, bn phi thc hin mt cch th t qua nhiu bc khc nhau. Chi tit cc bc thc hin khi s dng bin kiu d liu cursor trong Transaction-SQL. lm vic vi bin c kiu cursor, bn phi thc hin tng bc nh sau : nh ngha bin kiu cursor bng lnh DECLARE. S dng lnh OPEN m ra cursor nh ngha trc . c v x l trn tng dng d liu bn trong cursor. ng cursor li bng lnh CLOSE v DEALLOCATE. 2.1/- nh ngha bin c kiu cursor : Vic nh ngha bin c kiu cursor trong Transaction-SQL l vic ch nh n nhng dng d liu c bn trong cc bng d liu no m bin s tham chiu n. Thng thng trong lnh nh ngha bin c kiu cursor bn di s ch nh ra loi ca cursor cho cc mc ch s dng v sau ny thun tin hn. C php :

Trong : Tn cursor : tn ca bin kiu cursor. T kha LOCAL\GLOBAL : dng ch nh phm vi hot ng ca bin cursor hoc l cc b (local) bn trong mt th tc, l (batch) cc lnh, mt trigger hoc l ton cc (global) bn trong mt kt ni. Mt bin cursor c tnh ton cc s c php tham chiu trong bt k th tc no ca kt ni to ra bin cursor . T kha FORWARD_ONLY : dng ch nh vic c d liu trong cursor ch theo chiu i ti m thi (duyt t mu tin u tin n mu tin cui cng). T kha SCROLL : dng ch nh vic c d liu trong cursor c php di chuyn ti lui, qua li cc dng mu tin bn trong cursor ty thch. T kha STATIC : dng ch nh d liu c bn trong cursor l tnh. Khi nu nhng ngi dng khc c cc thay i bn di d liu gc (base table) th cc thay i s khng c cp nht t ng trong d liu ca cursor. Bi v khi d liu trong cursor chnh l d liu ca mt bng tm c h thng sao chp v lu tr trong c s d liu tempdb ca h thng khi ng ngha cursor.

T kha DYNAMIC : dng ch nh d liu bn trong cursor l ng. Khi vic cp nht d liu trong bng c s (base table) bi nhng ngi dng khc s c cp nht t ng trong d liu cursor c kiu l DYNAMIC. T kha KEYSET : c hot ng gn ging vi kiu DYNAMIC, cc thay i d liu trn cc ct khng l kha chnh trong bng c s bi nhng ngi dng khc s c cp nht trong d liu cursor. Tuy nhin i vi cc mu tin va thm mi hoc cc mu tin b hy b bi nhng ngi dng khc s khng c hin th trong d liu cursor c kiu l KEYSET. T kha READ_ONLY : dng ch nh d liu bn trong cursor l ch c nhm hn ch vic sa i d liu bn trong cursor. Khi khai bo cursor vi kiu d liu l tnh (STATIC) th d liu trong cursor xem nh l ch c. T kha SCROLL_LOCK : dng ch nh h thng Microsoft SQL Server t ng kha cc dng mu tin cn phi thay i gi tr hoc b hy b bn trong bng nhm m bo cc hnh ng cp nht lun lun thnh cng. Cu lnh SELECT : dng ch n cc ct c bn trong bng m bn cn c d liu. Cu lnh SELECT trong cursor khng th cha cc mnh : INTO, COMPUTE, COMPUTE BY. Danh sch cc ct cp nht : ch nh danh sch tn cc ct s c php thay i gi tr trong cursor. Mc nh tt c cc ct trong mnh SELECT s c php thay i gi tr nu d liu cursor khng phi l ch c. V d : nh ngha mt bin cursor cha ton b cc dng d liu bn trong bng VATTU, cc dng d liu trong cursor cho php c cp nht. Bn s dng lnh khai bo bin cursor nh sau :

V d : nh ngha mt bin cursor cha ton b cc dng d liu bn trong bng NHACC, cc d liu trong cursor ch c php c v vic c d liu trong cursor ch theo mt chiu ti. Bn s dng lnh khai bo bin cursor nh sau :

Nhn xt : v d trn, bn c th b i t kha READ_ONLY bi v bn thn t kha STATIC nh ngha d liu ca cursor l ch c. Tuy nhin bn nn ghi nh ngha ca tng t kha ring l nh ngha ra d liu ca cc cursor ng vi yu cu m mnh cn s dng. 2.2/- M cursor :

c th c c cc dng d liu bn trong cursor trc tin bn cn phi m cursor ra bng lnh OPEN. Hot ng bn trong ca lnh ny thc ra l h thng s thc hin cu lnh truy vn SELECT c ch nh trong lnh nh ngha bin cursor trc . Trong trng hp nu bn nh ngha s dng cursor vi kiu STATIC hoc KEYSET th h thng s to ra bng tm cha cc d liu kt qu ca lnh SELECT nm trong c s d liu tempdb. C php lnh OPEN nh sau :

Trong : Tn cursor : tn ca bin kiu cursor nh ngha trc bng lnh DECLARE. V d : m cc cursor nh ngha cc v d trn. Bn s dng lnh OPEN nh sau :

Hoc

Sau khi nh ngha v m bin cursor, hnh ng k tip m bn thng thc hin l vic c v x l d liu trong cursor. Bn s dng lnh FETCH cng vi cc t kha tng ng ch nh vic c cc dng d liu bn trong cursor theo mt th t no. 2.3/- c v x l d liu trong cursor : C php :

Trong : Cc t kha NEXT, PRIOR, FIRST, LAST : dng c d liu ca dng d liu k tip (next), dng d liu pha trc (prior), dng d liu u tin (first), dng d liu cui cng (last) so vi dng d liu hin hnh bn trong cursor. Sau khi c d liu thnh cng, dng d liu hin hnh s b thay i chnh l dng va mi c c. T kha ABSOLUTE : dng ch nh d liu chnh xc th n bn trong cursor. Vi n l s nguyn dng dng ch nh vic c d liu ti dng th n c m t dng u tin, vi n l s nguyn m dng ch nh vic c d liu ti dng th n c m ngc t dng cui cng tr ln. T kha RELATIVE : dng ch nh vic c d liu ti mt dng tng i so

vi dng d liu hin hnh. Vi n l mt s nguyn c th dng hoc m ch nh vic c theo chiu ti hoc lui so vi dng d liu hin hnh. Tn cursor : tn ca bin kiu cursor c nh ngha trc bng lnh DECLARE. Danh sch bin : danh sch tn cc bin cc b c nh ngha trc . Cc bin ny s lu tr cc gi tr d liu c c t lnh FETCH.

Minh ha vic c d liu theo cc th t khc nhau Trong qu trnh c v x l cc dng d liu khng m bo lun lun l thnh cng bi v c s truy cp bi nhng ngi dng khc hoc mt l do khc. Do h thng Microsoft SQL Server cung cp cho bn mt bin h thng c tn l @@FETCH_STATUS dng kim tra tnh trng c d liu l thnh cng hay tht bi. Gi tr ca bin tr v 0 khi vic c d liu l thnh cng. V d : c d liu cursor bng VATTU ch lc cc vt t l Tivi. Bn s dng cc lnh nh sau :

Kt qu tr v :

Nhn xt : trong v d trn, c ghi ch cc bc thc hin khi s dng bin cursor nhm gip bn d c, d hiu. Vic c d liu c thc hin trong vng lp

WHILE nhm tm ra tt c cc vt t l Tivi, s dng iu kin lp @@FETCH_STATUS = 0 ni rng nu vic c d liu ca lnh FETCH NEXt thnh cng th s tip tc lp. Hai lnh cui cng CLOSE v DEALLOCATE dng ng li cursor sau khi c v x l d liu xong. V d : cp nht gi tr d liu cho ct TGNHAP (tr gi nhp) trong bng PNHAP bng cch duyt qua tng phiu nhp, tnh ra tr gi nhp ca tng phiu cn c vo s lng nhp v n gi nhp ca tng vt t trong bng CTPNHAP, sau cng cp nht vo ct TGNHAP. Bn s dng cc lnh nh sau thc hin cc hnh ng m t nh trn :

Nhn xt : trong v d trn, s dng vng lp WHILE m iu kin lp l 0 = 0 ch nh iu kin so snh vng lp l lun lun ng. Do , bn trong vng lp ny bn bt buc phi thot khi vng lp bng lnh BREAK v iu kin thot l khi vic c d liu b li (@@FETCH_STATUS <> 0). Ngoi vic cp nht d liu bng lnh UPDATE m trong mnh WHERE c s dng t kha CRRENT OF dng ch nh vic cp nht d liu trn dng d liu hin hnh ca cursor. 2.4/- ng cursor : y l cng vic sau cng cn phi thc hin khi s dng bin c kiu cursor. Thng thng ng cursor bn phi hp c hai lnh m t nh bn di : C php :

Trong : Tn cursor : tn ca bin kiu cursor c nh ngha v m ra trc . Lnh CLOSE ch l thc hin hnh ng gii phng cc dng d liu tham chiu bn trong bin cursor, bn c th m li cursor m khng cn thit phi nh ngha li bin cursor bng lnh DECLARE. Tuy nhin vic c d liu s khng cn l hp l na sau khi bn ra lnh CLOSE ng cursor. Lnh DEALLOCATE gii phng tht s bin cursor ra khi b nh. Sau khi thc hin lnh ny, nu c lnh no tham chiu n tn cursor u s gy ra li. S minh ha cc bc thc hin khi s dng bin c kiu d liu cursor :

Tin ch duy nht khi lm vic vi cursor l chng cho php bn c th duyt tun t trn cc dng d liu (ging nh i tng recordset ca ADO hoc DAO trong ngn ng lp trnh Visual Basic), tuy nhin Microsft SQL Server khuyn co bn khng nn lm dng qu nhiu cc hnh ng cp nht d liu bng cursor bi v n s lm cho cc x l ny chm. Bng chng l bn c th tnh ton gi tr cho ct tr gi nhp (TGNHAP) trong bng PNHAP bng mt lnh UPDATE duy nht thay v phi s dng qu nhiu lnh cho cc x l trong cursor.

Tm li, bn ch s dng kiu d liu cursor trong Transaction-SQL gii quyt cc vn : Microsoft SQL Server l mt h qun tr c s d liu quan h (Relational DataBase Managament System) do chng lun chn cc gii php lm vic trn b cc mu tin. K tip khi cn gii quyt cc vn cp nht d liu th bn lun lun u tin

chn ra cc hng gii quyt trn b cc mu tin bi v khi s lm cho cc x l c nhanh hn. Sau cng cc hng gii quyt theo kiu cursor ch l gii php sau cng nht chn la khi khng cn gii php no tt hn.

//--------------------------------------------------------------------------------------------------------------------------------------================================================== =================================//

Mt v d v cursor trong SQL Server


Posted on 25/06/2010 by truonggiang83 Xin cho tt c cc bn, nhng ai ang theo hc mn CSDL th cng tng hoc s hc qua Cursor. hiu r hn v vn ny chng ta theo di bi ton sau: Yu cu: Ti mun backup tt c Database trong h thng (h qun tr CSDL SQL Server 2005 lm v d) Hng gii quyt: Bn hy xem tt c DataBase trong h thng l mt danh sch. Chng ta s duyt danh sch ny theo tng dng v mi dng bn thc hin thao tc Backup tng ng vi n. Phn tch: -Nn t tn DataBase s backup theo dng: TenDataBase_Ngay_+.bak -To mt con tr duyt danh sch cc DataBase ca h thng. -Thc hin BackupData tng ng. Mu code: DECLARE @name VARCHAR(50) Tn Databse s duyt DECLARE @path VARCHAR(256) ng dn file backup DECLARE @fileName VARCHAR(256) tn file backup DECLARE @fileDate VARCHAR(20) ng dn t theo tn tng file backup SET @path = D:\ThuMucbackUp\ thu muc chua cac file duoc Backup SELECT @fileDate = CONVERT(VARCHAR(20),GETDATE(),112)ngay thang se backup nh ngha Cursor DECLARE db_cursor CURSOR FOR SELECT name FROM master.dbo.sysdatabases ly danh sch tn DataBase t h thng WHERE name NOT IN (master,'model,'msdb,'tempdb) nhng DataBase khng cn backup, nu bn mun backup ht th b dng ny OPEN db_cursor m con tr duyt danh sch FETCH NEXT FROM db_cursor INTO @name

WHILE @@FETCH_STATUS = 0 BEGIN SET @fileName = @path + @name + _ + @fileDate + .BAK Tn Datase s c lu. BACKUP DATABASE @name TO DISK = @fileName FETCH NEXT FROM db_cursor INTO @name duyet record k tip END CLOSE db_cursor ng con tr DEALLOCATE db_cursor gii phng con tr
//================================================= ================================================== ================================================== =================//

How to Create and Use a Sample SQL Cursor and T-SQL Cursor Example Code
Here is a SQL cursor example code created for looping through a list of records as a result of a select query, which enables the sql developer to execute a stored procedure for each row in the cursor which use the values fetched by the cursor as the input arguments. The sample cursor is developed on a MS SQL Server and is a sample for sql server cursor. The sql codes may use tsql codes so the sql cursor example may have differences than a typical pl/sql cursor or an Oracle cursor. The sample sql cursor codes below illustrates a process of merging duplicate customer records kept in an application database. Assume that the duplicate customers list and relation among the duclicate customer records are inserted into and kept in a table named DuplicateCustomers which is simply formed of columns MasterCustomerId, DuplicateCustomerId and some other columns like MergeDate, IsMerged, MergedByUserId, InsertedDate, InsertedByUserId, etc which are used during processing some details and useful in the reporting of the duplicate record merge process results.

The list of the original customer records and the duplicate customer records can be selected by the sql select query below:
SELECT MasterCustomerId, DuplicateCustomerId FROM DuplicateCustomers WHERE IsMerged = 0

You can either create a temporary table to keep the result set in order to use your initial set of records in the next steps of your process. Or you can just use the above transact sql query to supply your records set to feed the t-sql cursor example we will create. Here with the variable declarations we will set column values we fetch with the tsql cursor to the variables.

DECLARE @MergeDate Datetime DECLARE @MasterId Int DECLARE @DuplicateId Int

Then the sql cursor definition or the t-sql cursor declaration code takes place.
DECLARE merge_cursor CURSOR FAST_FORWARD FOR SELECT MasterCustomerId, DuplicateCustomerId FROM DuplicateCustomers WHERE IsMerged = 0

During the example sql cursor declaration you can set the sql cursor properties or the attributes of the cursor. Note that the sample cursor declaration uses the FAST_FORWARD key attribute in order to create a sql cursor with a high performance. Since FAST_FORWARD states that the cursor is FORWARD_ONLY and READ_ONLY the performance of the cursor is optimized. The t-sql syntax of cursor declaration command DECLARE CURSOR is stated as below in MSDN :
DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ] [ FORWARD_ONLY | SCROLL ] [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ] [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ] [ TYPE_WARNING ] FOR select_statement [ FOR UPDATE [ OF column_name [ ,...n ] ] ]

You can find more on how to declare a t-sql cursor and cursor attributes in Books Online With the call of the OPEN command the t-sql server cursor is opened and the cursor is populated with the data by the execution of the select query of the DECLARE CURSOR command.
OPEN merge_cursor

So the OPEN command runs or executes the "SELECT MasterCustomerId, DuplicateCustomerId FROM DuplicateCustomers WHERE IsMerged = 0" select query defined in the DECLARE CURSOR definition command which is set after FOR key. With the execution of this select query the cursor is populated with the rows or the data returned as a result set of the query. The next step in using a cursor is fetching the rows from the populated cursor one by one.
FETCH NEXT FROM merge_cursor INTO @MasterId, @DuplicateId

The syntax of the FETCH command is as follows


FETCH [ [ NEXT | PRIOR | FIRST | LAST | ABSOLUTE { n | @nvar } | RELATIVE { n | @nvar } ] FROM ] { { [ GLOBAL ] cursor_name } | @cursor_variable_name } [ INTO @variable_name [ ,...n ] ]

With the use of the NEXT, the FETCH NEXT command returns the next row following the current row. If FETCH NEXT is called for the first time for a cursor, or we can say if it is called after the OPEN CURSOR command, then the first row in the returned result set is fetched or returned. The column values in the returned row can be set into variables with the INTO key and by giving the names of the variables as a comma seperated list after the INTO key. So for our example the first row in the return result set of the cursor is set into two variables named @MasterId and @DuplicateId. Here one important point is the first column of the result set (column named MasterCustomerId) is set to first variable defined in the list which is the @MasterId variable. And the secod column named DuplicateCustomerId is set to the second variable @DuplicateId. So the variable types must be carefully declared according to the column types of the selected rows. After the FETCH command, you should always control the value of the @@FETCH_STATUS. This variable returns the status of the last cursor FETCH command in the current connection. The possible return values of @@FETCH_STATUS are;
0 FETCH statement was successful -1 FETCH statement failed or the row was beyond the result set

-2 Row fetched is missing

By always checking the @@FETCH_STATUS and controlling that it is value is equal to "0" we will have a new row fetched. When the fetched status is different than the "0" we can say that we have no more records are fetched. In short, the value of @@FETCH_STATUS variable is the controlling parameter of the loop we will use during processing all records or rows in the cursor. In the body part of the WHILE statement the codes to process each row returned by the cursor takes place. This code block changes according to your reason to create and use a cursor. I placed an EXEC call for a sql stored procedure and an UPDATE sql statement here in order to show as a sample. The most important thing to care for the inside codes of the WHILE code block is the last code statement FETCH NEXT command is recalled to get the next row from the return cursor data set. After all the records are processed the @@FETCH_STATUS parameter returns -1, so the cursor can be now closed with the CLOSE CURSOR command. CLOSE CURSOR releases the current result set. And the DEALLOCATE CURSOR command releases the last cursor reference. Here you can find the full sql cursor example code used in this article for explaining the t-sql cursors in SQL Server.
DECLARE @MergeDate Datetime DECLARE @MasterId Int DECLARE @DuplicateId Int

SELECT @MergeDate = GetDate()

DECLARE merge_cursor CURSOR FAST_FORWARD FOR SELECT MasterCustomerId, DuplicateCustomerId FROM DuplicateCustomers WHERE IsMerged = 0 OPEN merge_cursor FETCH NEXT FROM merge_cursor INTO @MasterId, @DuplicateId WHILE @@FETCH_STATUS = 0 BEGIN EXEC MergeDuplicateCustomers @MasterId, @DuplicateId UPDATE DuplicateCustomers SET IsMerged = 1, MergeDate = @MergeDate WHERE MasterCustomerId = @MasterId AND DuplicateCustomerId = @DuplicateId FETCH NEXT FROM merge_cursor INTO @MasterId, @DuplicateId END CLOSE merge_cursor DEALLOCATE merge_cursor

//================================================= ================================================== ================================================== ================//

DECLARE CURSOR (Transact-SQL)


SQL Server 2008 R2 Other Versions

15 out of 21 rated this helpful Rate this topic

Defines the attributes of a Transact-SQL server cursor, such as its scrolling behavior and the query used to build the result set on which the cursor operates. DECLARE CURSOR accepts both a syntax based on the ISO standard and a syntax using a set of Transact-SQL extensions. Transact-SQL Syntax Conventions
Syntax

ISO Syntax DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR FOR select_statement [ FOR { READ ONLY | UPDATE [ OF column_name [ ,...n ] ] } ] [;] Transact-SQL Extended Syntax DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ] [ FORWARD_ONLY | SCROLL ] [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ] [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ] [ TYPE_WARNING ] FOR select_statement [ FOR UPDATE [ OF column_name [ ,...n ] ] ] [;]

Arguments

cursor_name

Is the name of the Transact-SQL server cursor defined. cursor_name must conform to the rules for identifiers. For more information about rules for identifiers, see Using Identifiers As Object Names.
INSENSITIVE

Defines a cursor that makes a temporary copy of the data to be used by the cursor. All requests to the cursor are answered from this temporary table in tempdb; therefore, modifications made to base tables are not reflected in the data returned by fetches made to this cursor, and this cursor does not allow modifications. When ISO syntax is used, if INSENSITIVE is omitted, committed deletes and updates made to the underlying tables (by any user) are reflected in subsequent fetches.
SCROLL

Specifies that all fetch options (FIRST, LAST, PRIOR, NEXT, RELATIVE, ABSOLUTE) are available. If SCROLL is not specified in an ISO DECLARE CURSOR, NEXT is the only fetch option supported. SCROLL cannot be specified if FAST_FORWARD is also specified.
select_statement

Is a standard SELECT statement that defines the result set of the cursor. The keywords COMPUTE, COMPUTE BY, FOR BROWSE, and INTO are not allowed within select_statement of a cursor declaration. SQL Server implicitly converts the cursor to another type if clauses in select_statement conflict with the functionality of the requested cursor type. For more information, see Using Implicit Cursor Conversions.
READ ONLY

Prevents updates made through this cursor. The cursor cannot be referenced in a WHERE CURRENT OF clause in an UPDATE or DELETE statement. This option overrides the default capability of a cursor to be updated.
UPDATE [OF column_name [,...n]]

Defines updatable columns within the cursor. If OF column_name [,...n] is specified, only the columns listed allow modifications. If UPDATE is specified without a column list, all columns can be updated.
cursor_name

Is the name of the Transact-SQL server cursor defined. cursor_name must conform to the rules for identifiers. For more information about rules for identifiers, see Using Identifiers As Object Names.
LOCAL

Specifies that the scope of the cursor is local to the batch, stored procedure, or trigger in which the cursor was created. The cursor name is only valid within this scope. The cursor can be referenced by local cursor variables in the batch, stored procedure, or trigger, or a stored procedure OUTPUT parameter. An OUTPUT parameter is used to pass the local cursor back to the calling batch, stored procedure, or trigger, which can assign the parameter to a cursor variable to reference the cursor after the stored procedure terminates. The cursor is implicitly deallocated when the batch, stored procedure, or trigger terminates, unless the cursor was passed back in an OUTPUT parameter. If it is passed back in an OUTPUT parameter, the cursor is deallocated when the last variable referencing it is deallocated or goes out of scope.
GLOBAL

Specifies that the scope of the cursor is global to the connection. The cursor name can be referenced in any stored procedure or batch executed by the connection. The cursor is only implicitly deallocated at disconnect.
Note

If neither GLOBAL or LOCAL is specified, the default is controlled by the setting of the default to local cursor database option. In SQL Server version 7.0, this option defaults to FALSE to match earlier versions of SQL Server, in which all cursors were global. The default of this option may change in future versions of SQL Server. For more information, see Setting Database Options.
FORWARD_ONLY

Specifies that the cursor can only be scrolled from the first to the last row. FETCH NEXT is the only supported fetch option. If FORWARD_ONLY is specified without the STATIC, KEYSET, or DYNAMIC keywords, the cursor operates as a DYNAMIC cursor. When neither FORWARD_ONLY nor SCROLL is specified, FORWARD_ONLY is the default, unless the keywords STATIC, KEYSET, or DYNAMIC are specified. STATIC, KEYSET, and DYNAMIC cursors default to SCROLL. Unlike database APIs such as ODBC and ADO, FORWARD_ONLY is supported with STATIC, KEYSET, and DYNAMIC Transact-SQL cursors.
STATIC

Defines a cursor that makes a temporary copy of the data to be used by the cursor. All requests to the cursor are answered from this temporary table in tempdb; therefore, modifications made to base tables are not reflected in the data returned by fetches made to this cursor, and this cursor does not allow modifications.
KEYSET

Specifies that the membership and order of rows in the cursor are fixed when the cursor is opened. The set of keys that uniquely identify the rows is built into a table in tempdb known as the keyset.
Note

If the query references at least one table without a unique index, the keyset cursor is converted to a static cursor. Changes to nonkey values in the base tables, either made by the cursor owner or committed by other users, are visible as the owner scrolls around the cursor. Inserts made by other users are not visible (inserts cannot be made through a Transact-SQL server cursor). If a row is deleted, an attempt to fetch the row returns an @@FETCH_STATUS of -2. Updates of key values from outside the cursor resemble a delete of the old row followed by an insert of the new row. The row with the new values is not visible, and attempts to fetch the row with the old values return an @@FETCH_STATUS of -2. The new values are visible if the update is done through the cursor by specifying the WHERE CURRENT OF clause.
DYNAMIC

Defines a cursor that reflects all data changes made to the rows in its result set as you scroll around the cursor. The data values, order, and membership of the rows can change on each fetch. The ABSOLUTE fetch option is not supported with dynamic cursors.
FAST_FORWARD

Specifies a FORWARD_ONLY, READ_ONLY cursor with performance optimizations enabled. FAST_FORWARD cannot be specified if SCROLL or FOR_UPDATE is also specified.
Note

In SQL Server 2000, FAST_FORWARD and FORWARD_ONLY cursor options are

mutually exclusive. If both are specified, an error is raised. In SQL Server 2005 and later, both keywords can be used in the same DECLARE CURSOR statement.
READ_ONLY

Prevents updates made through this cursor. The cursor cannot be referenced in a WHERE CURRENT OF clause in an UPDATE or DELETE statement. This option overrides the default capability of a cursor to be updated.
SCROLL_LOCKS

Specifies that positioned updates or deletes made through the cursor are guaranteed to succeed. SQL Server locks the rows as they are read into the cursor to ensure their availability for later modifications. SCROLL_LOCKS cannot be specified if FAST_FORWARD or STATIC is also specified.
OPTIMISTIC

Specifies that positioned updates or deletes made through the cursor do not succeed if the row has been updated since it was read into the cursor. SQL Server does not lock rows as they are read into the cursor. It instead uses comparisons of timestamp column values, or a checksum value if the table has no timestamp column, to determine whether the row was modified after it was read into the cursor. If the row was modified, the attempted positioned update or delete fails. OPTIMISTIC cannot be specified if FAST_FORWARD is also specified.
TYPE_WARNING

Specifies that a warning message is sent to the client when the cursor is implicitly converted from the requested type to another.
select_statement

Is a standard SELECT statement that defines the result set of the cursor. The keywords COMPUTE, COMPUTE BY, FOR BROWSE, and INTO are not allowed within select_statement of a cursor declaration.
Note

You can use a query hint within a cursor declaration; however, if you also use the FOR UPDATE OF clause, specify OPTION (query_hint) after FOR UPDATE OF. SQL Server implicitly converts the cursor to another type if clauses in select_statement conflict with the functionality of the requested cursor type. For more information, see Implicit Cursor Conversions.
FOR UPDATE [OF column_name [,...n]]

Defines updatable columns within the cursor. If OF column_name [,...n] is supplied, only the columns listed allow modifications. If UPDATE is specified without a column list, all columns can be updated, unless the READ_ONLY concurrency option was specified.
Remarks

DECLARE CURSOR defines the attributes of a Transact-SQL server cursor, such as its scrolling behavior and the query used to build the result set on which the cursor operates. The OPEN statement populates the result set, and FETCH returns a row from the result set. The CLOSE statement releases the current result set associated with the cursor. The DEALLOCATE statement releases the resources used by the cursor. The first form of the DECLARE CURSOR statement uses the ISO syntax for declaring cursor behaviors. The second form of DECLARE CURSOR uses Transact-SQL extensions that allow you to define cursors using the same cursor types used in the database API cursor functions of ODBC or ADO. You cannot mix the two forms. If you specify the SCROLL or INSENSITIVE keywords before the CURSOR keyword, you cannot use any keywords between the CURSOR and FOR select_statement keywords. If you specify any keywords between the CURSOR and FOR select_statement keywords, you cannot specify SCROLL or INSENSITIVE before the CURSOR keyword. If a DECLARE CURSOR using Transact-SQL syntax does not specify READ_ONLY, OPTIMISTIC, or SCROLL_LOCKS, the default is as follows: If the SELECT statement does not support updates (insufficient permissions, accessing remote tables that do not support updates, and so on), the cursor is READ_ONLY. STATIC and FAST_FORWARD cursors default to READ_ONLY. DYNAMIC and KEYSET cursors default to OPTIMISTIC.

Cursor names can be referenced only by other Transact-SQL statements. They cannot be referenced by database API functions. For example, after declaring a cursor, the cursor name cannot be referenced from OLE DB, ODBC or ADO functions or methods. The cursor rows cannot be fetched using the fetch functions or methods of the APIs; the rows can be fetched only by Transact-SQL FETCH statements. After a cursor has been declared, these system stored procedures can be used to determine the characteristics of the cursor. System stored procedures sp_cursor_list sp_describe_cursor Description Returns a list of cursors currently visible on the connection and their attributes. Describes the attributes of a cursor, such as whether it is a forward-only or scrolling cursor.

sp_describe_cursor_columns Describes the attributes of the columns in the cursor result set. sp_describe_cursor_tables Describes the base tables accessed by the cursor.

Variables may be used as part of the select_statement that declares a cursor. Cursor variable values do not change after a cursor is declared. In SQL Server version 6.5 and earlier, variable values are refreshed every time a cursor is reopened.
Permissions

DECLARE CURSOR permissions default to any user that has SELECT permissions on the views, tables, and columns used in the cursor.
Examples

A. Using simple cursor and syntax

The result set generated at the opening of this cursor includes all rows and all columns in the table. This cursor can be updated, and all updates and deletes are represented in fetches made against this cursor. FETCH NEXT is the only fetch available because the SCROLL option has not been specified.
USE AdventureWorks2008R2; GO DECLARE vend_cursor CURSOR FOR SELECT BusinessEntityID, Name, CreditRating FROM Purchasing.Vendor OPEN vend_cursor FETCH NEXT FROM vend_cursor;

B. Using nested cursors to produce report output

The following example shows how cursors can be nested to produce complex reports. The inner cursor is declared for each vendor.
USE AdventureWorks2008R2; GO SET NOCOUNT ON; DECLARE @vendor_id int, @vendor_name nvarchar(50), @message varchar(80), @product nvarchar(50); PRINT '-------- Vendor Products Report --------'; DECLARE vendor_cursor CURSOR FOR SELECT BusinessEntityID, Name FROM Purchasing.Vendor WHERE PreferredVendorStatus = 1 ORDER BY BusinessEntityID; OPEN vendor_cursor; FETCH NEXT FROM vendor_cursor INTO @vendor_id, @vendor_name; WHILE @@FETCH_STATUS = 0 BEGIN PRINT ' '; SELECT @message = '----- Products From Vendor: ' + @vendor_name; PRINT @message; -- Declare an inner cursor based

-- on vendor_id from the outer cursor. DECLARE product_cursor CURSOR FOR SELECT v.Name FROM Purchasing.ProductVendor AS pv INNER JOIN Production.Product AS v ON pv.ProductID = v.ProductID AND pv.BusinessEntityID = @vendor_id; outer cursor

-- Variable value from the

OPEN product_cursor; FETCH NEXT FROM product_cursor INTO @product; IF @@FETCH_STATUS <> 0 PRINT ' <<None>>' ; WHILE @@FETCH_STATUS = 0 BEGIN SELECT @message = ' ' + @product PRINT @message FETCH NEXT FROM product_cursor INTO @product; END; CLOSE product_cursor; DEALLOCATE product_cursor; -- Get the next vendor. FETCH NEXT FROM vendor_cursor INTO @vendor_id, @vendor_name;

END CLOSE vendor_cursor; DEALLOCATE vendor_cursor;

See Also

Reference @@FETCH_STATUS (Transact-SQL) CLOSE (Transact-SQL) Cursors (Transact-SQL) DEALLOCATE (Transact-SQL) FETCH (Transact-SQL) SELECT (Transact-SQL) sp_configure (Transact-SQL)
Top of Form

Did you find this helpful?

Yes

No

Bottom of Form

Community Content Add FAQ Cursor To Find Orphaned Records $0--Hopefully, this displays properly on the msdn website. This is my 3rd, and final, time uploading this text.$0 $0$0 $0 $0DECLARE @_ColumnName NVARCHAR(500) $0 $0DECLARE @_PrimaryTableName NVARCHAR(500) $0 $0DECLARE @_ColumnType NVARCHAR(500) $0 $0$0 $0 $0--Change the following three values to meet your needs. $0 $0SET @_ColumnName = 'PolicyID' $0 $0SET @_PrimaryTableName = 'tbl_policies' $0 $0SET @_ColumnType = 'int' $0 $0SET nocount ON $0 $0$0 $0 $0DECLARE orph_cursor CURSOR FOR $0 $0 SELECT a.name AS tablename, $0 $0 b.name AS columnname $0 $0 FROM sys.tables a $0 $0 INNER JOIN sys.columns b $0 $0 ON a.object_id = b.object_id $0 $0 INNER JOIN sys.types c $0 $0 ON b.system_type_id = c.system_type_id $0 $0 WHERE b.name LIKE '%' + @_ColumnName + '%' $0 $0 AND c.name = @_ColumnType $0 $0$0 $0 $0OPEN orph_cursor $0 $0$0 $0 $0DECLARE @TableName VARCHAR(500) $0 $0DECLARE @ColumnName VARCHAR(500) $0 $0DECLARE @Query NVARCHAR(500) $0 $0DECLARE @RowCount NVARCHAR(500) $0 $0$0 $0 $0FETCH NEXT FROM orph_cursor INTO @TableName, @ColumnName $0 $0$0 $0 $0WHILE @@FETCH_STATUS = 0 $0 $0 BEGIN $0 $0 SET @Query = 'SELECT * FROM ' + @TableName + ' WHERE ' + @ColumnName + $0 $0 ' NOT IN (SELECT ' + $0 $0 @_ColumnName + ' FROM ' + @_PrimaryTableName + $0 $0 ')' $0 $0$0 $0 $0 EXEC Sp_executesql @Query $0 $0$0 $0 $0 SELECT @RowCount = @@ROWCOUNT $0 $0$0 $0 $0 IF @RowCount <> 0 $0 $0 BEGIN $0 $0 PRINT @Query $0 $0$0 $0 $0 PRINT @TableName + ' - ' + @RowCount $0 $0$0 $0 $0 PRINT '----------' $0 $0 END $0 $0$0 $0 $0 FETCH NEXT FROM orph_cursor INTO @TableName, @ColumnName $0 $0 END $0 $0$0 $0 $0CLOSE orph_cursor $0 $0$0 $0 $0DEALLOCATE orph_cursor$0 $0$0 $0 History

2/6/2012 Dataknox

2/6/2012

Dataknox

Use cursor to change the permissions of all Stored Procedures We can use cursor to grant execute permission to all the stored procedures in a database. $0See the code below: DECLARE Proc_Cursor CURSOR FOR SELECT name FROM sysobjects WHERE type = 'P' and xtype = 'P' OPEN Proc_Cursor DECLARE @Name VARCHAR(500) DECLARE @Query VARCHAR(500) FETCH NEXT FROM Proc_Cursor INTO @Name; WHILE @@FETCH_STATUS = 0 BEGIN SET @Query = 'GRANT EXEC ON ' + @Name + ' To Public' EXEC(@Query) FETCH NEXT FROM Proc_Cursor INTO @Name; END CLOSE Proc_Cursor DEALLOCATE Proc_Cursor

You might also like