DECLARE CURSOR
DECLARE @license_id numeric(9)
DECLARE license_cursor CURSOR FOR --建立游標使用結果集
select license_id from license where license_id = 3
OPEN license_cursor --填充結果集
FETCH NEXT FROM license_cursor into @license_id --從結果集返回行
CLOSE license_cursor --釋放與游標關(guān)聯(lián)的結果集
DEALLOCATE license_cursor --釋放游標所占資源
@@FETCH_STATUS
0表示FETCH成功,
-1表示FETCH失敗
NEXT 返回緊跟當前行之后的結果行,并且當前行遞增為結果行。如果 FETCH NEXT 為對游標的第一次提取操作,則返回結果集中的第一行。
NEXT 為默認的游標提取選項。
PRIOR 返回緊臨當前行前面的結果行,并且當前行遞減為結果行。如果 FETCH PRIOR 為對游標的第一次提取操作,則沒(méi)有行返回并且游標置于第一行之前
FIRST 返回游標中的第一行并將其作為當前行。
LAST 返回游標中的最后一行并將其作為當前行。
I(yíng)NTO @variable_name[,...n] 允許將提取操作的列數據放到局部變量中。列表中的各個(gè)變量從左到右與游標結果集中的相應列相關(guān)聯(lián)。各變量的數據類(lèi)型必須與相應的結果列的數據類(lèi)型匹配或是結果列數據類(lèi)型所支持的隱性轉換。變量的數目必須與游標選擇列表中的列的數目一致。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Transact-SQL 參考
DECLARE CURSOR
定義 Transact-SQL 服務(wù)器游標的特性,例如游標的滾動(dòng)行為和用于生成游標對其進(jìn)行操作的結果集的查詢(xún)。DECLARE CURSOR 接受基于 SQL-92 標準的語(yǔ)法和使用一組 Transact-SQL 擴展的語(yǔ)法。
SQL-92 語(yǔ)法
DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR
FOR select_statement
[ FOR { READ ONLY | UPDATE [ OF column_name [ ,...n ] ] } ]
Transact-SQL 擴展語(yǔ)法
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 ] ] ]
SQL-92 參數
cursor_name
是所定義的 Transact-SQL 服務(wù)器游標名稱(chēng)。cursor_name 必須遵從標識符規則。有關(guān)標識符規則的更多信息,請參見(jiàn)使用標識符。
INSENSITIVE
定義一個(gè)游標,以創(chuàng )建將由該游標使用的數據的臨時(shí)復本。對游標的所有請求都從 tempdb 中的該臨時(shí)表中得到應答;因此,在對該游標進(jìn)行提取操作時(shí)返回的數據中不反映對基表所做的修改,并且該游標不允許修改。使用 SQL-92 語(yǔ)法時(shí),如果省略 INSENSITIVE,(任何用戶(hù))對基表提交的刪除和更新都反映在后面的提取中。
SCROLL
指定所有的提取選項(FIRST、LAST、PRIOR、NEXT、RELATIVE、ABSOLUTE)均可用。如果在 SQL-92 DECLARE CURSOR 中未指定 SCROLL,則 NEXT 是唯一支持的提取選項。如果指定 SCROLL,則不能也指定 FAST_FORWARD。
select_statement
是定義游標結果集的標準 SELECT 語(yǔ)句。在游標聲明的 select_statement 內不允許使用關(guān)鍵字 COMPUTE、COMPUTE BY、FOR BROWSE 和 INTO。
如果 select_statement 中的子句與所請求的游標類(lèi)型的功能發(fā)生沖突,則 Microsoft® SQL Server™ 隱性地將游標轉換為另一種類(lèi)型。有關(guān)更多信息,請參見(jiàn)隱性游標轉換。
READ ONLY
Prevents updates made through this cursor.在 UPDATE 或 DELETE 語(yǔ)句的 WHERE CURRENT OF 子句中不能引用游標。該選項替代要更新的游標的默認功能。
UPDATE [OF column_name [,...n]]
定義游標內可更新的列。如果指定 OF column_name [,...n] 參數,則只允許修改所列出的列。如果在 UPDATE 中未指定列的列表,則可以更新所有列。
Transact-SQL 擴展參數
cursor_name
是所定義的 Transact-SQL 服務(wù)器游標名稱(chēng)。cursor_name 必須遵從標識符規則。有關(guān)標識符規則的更多信息,請參見(jiàn)使用標識符。
LOCAL
指定該游標的作用域對在其中創(chuàng )建它的批處理、存儲過(guò)程或觸發(fā)器是局部的。該游標名稱(chēng)僅在這個(gè)作用域內有效。在批處理、存儲過(guò)程、觸發(fā)器或存儲過(guò)程 OUTPUT 參數中,該游標可由局部游標變量引用。OUTPUT 參數用于將局部游標傳遞回調用批處理、存儲過(guò)程或觸發(fā)器,它們可在存儲過(guò)程終止后給游標變量指派參數使其引用游標。除非 OUTPUT 參數將游標傳遞回來(lái),否則游標將在批處理、存儲過(guò)程或觸發(fā)器終止時(shí)隱性釋放。如果 OUTPUT 參數將游標傳遞回來(lái),游標在最后引用它的變量釋放或離開(kāi)作用域時(shí)釋放。
GLOBAL
指定該游標的作用域對連接是全局的。在由連接執行的任何存儲過(guò)程或批處理中,都可以引用該游標名稱(chēng)。該游標僅在脫接時(shí)隱性釋放。
說(shuō)明 如果 GLOBAL 和 LOCAL 參數都未指定,則默認值由 default to local cursor 數據庫選項的設置控制。在 SQL Server 7.0 版中,該選項默認為 FALSE 以與 SQL Server 早期版本相匹配,在 SQL Server 早期版本中所有游標都是全局的。該選項的默認值在以后的 SQL Server 版本中可能會(huì )更改。有關(guān)更多信息,請參見(jiàn)設置數據庫選項。
FORWARD_ONLY
指定游標只能從第一行滾動(dòng)到最后一行。FETCH NEXT 是唯一受支持的提取選項。如果在指定 FORWARD_ONLY 時(shí)不指定 STATIC、KEYSET 和 DYNAMIC 關(guān)鍵字,則游標作為 DYNAMIC 游標進(jìn)行操作。如果 FORWARD_ONLY 和 SCROLL 均未指定,除非指定 STATIC、KEYSET 或 DYNAMIC 關(guān)鍵字,否則默認為 FORWARD_ONLY。STATIC、KEYSET 和 DYNAMIC 游標默認為 SCROLL。與 ODBC 和 ADO這類(lèi)數據庫 API 不同,STATIC、KEYSET 和 DYNAMIC Transact-SQL 游標支持 FORWARD_ONLY。FAST_FORWARD 和 FORWARD_ONLY 是互斥的;如果指定一個(gè),則不能指定另一個(gè)。
STATIC
定義一個(gè)游標,以創(chuàng )建將由該游標使用的數據的臨時(shí)復本。對游標的所有請求都從 tempdb 中的該臨時(shí)表中得到應答;因此,在對該游標進(jìn)行提取操作時(shí)返回的數據中不反映對基表所做的修改,并且該游標不允許修改。
KEYSET
指定當游標打開(kāi)時(shí),游標中行的成員資格和順序已經(jīng)固定。對行進(jìn)行唯一標識的鍵集內置在 tempdb 內一個(gè)稱(chēng)為 keyset 的表中。對基表中的非鍵值所做的更改(由游標所有者更改或由其它用戶(hù)提交)在用戶(hù)滾動(dòng)游標時(shí)是可視的。其他用戶(hù)進(jìn)行的插入是不可視的(不能通過(guò) Transact-SQL 服務(wù)器游標進(jìn)行插入)。如果某行已刪除,則對該行的提取操作將返回 @@FETCH_STATUS 值 -2。從游標外更新鍵值類(lèi)似于刪除舊行后接著(zhù)插入新行的操作。含有新值的行不可視,對含有舊值的行的提取操作將返回 @@FETCH_STATUS 值 -2。如果通過(guò)指定 WHERE CURRENT OF 子句用游標完成更新,則新值可視。
DYNAMIC
定義一個(gè)游標,以反映在滾動(dòng)游標時(shí)對結果集內的行所做的所有數據更改。行的數據值、順序和成員在每次提取時(shí)都會(huì )更改。動(dòng)態(tài)游標不支持 ABSOLUTE 提取選項。
FAST_FORWARD
指定啟用了性能優(yōu)化的 FORWARD_ONLY、READ_ONLY 游標。如果指定 FAST_FORWARD,則不能也指定 SCROLL 或 FOR_UPDATE。FAST_FORWARD 和 FORWARD_ONLY 是互斥的;如果指定一個(gè),則不能指定另一個(gè)。
READ_ONLY
禁止通過(guò)該游標進(jìn)行更新。在 UPDATE 或 DELETE 語(yǔ)句的 WHERE CURRENT OF 子句中不能引用游標。該選項替代要更新的游標的默認功能。
SCROLL_LOCKS
指定確保通過(guò)游標完成的定位更新或定位刪除可以成功。當將行讀入游標以確保它們可用于以后的修改時(shí),Microsoft® SQL Server™ 會(huì )鎖定這些行。如果還指定了 FAST_FORWARD,則不能指定 SCROLL_LOCKS。
OPTIMISTIC
指定如果行自從被讀入游標以來(lái)已得到更新,則通過(guò)游標進(jìn)行的定位更新或定位刪除不成功。當將行讀入游標時(shí) SQL Server 不鎖定行。相反,SQL Server 使用 timestamp 列值的比較,或者如果表沒(méi)有 timestamp 列則使用校驗值,以確定將行讀入游標后是否已修改該行。如果已修改該行,嘗試進(jìn)行的定位更新或定位刪除將失敗。如果還指定了 FAST_FORWARD,則不能指定 OPTIMISTIC。
TYPE_WARNING
指定如果游標從所請求的類(lèi)型隱性轉換為另一種類(lèi)型,則給客戶(hù)端發(fā)送警告消息。
select_statement
是定義游標結果集的標準 SELECT 語(yǔ)句。在游標聲明的 select_statement 內不允許使用關(guān)鍵字 COMPUTE、COMPUTE BY、FOR BROWSE 和 INTO。
如果 select_statement 內的子句與所請求的游標類(lèi)型沖突,SQL Server 將游標隱性轉換成另一種類(lèi)型。有關(guān)更多信息,請參見(jiàn)隱性游標轉換。
UPDATE [OF column_name [,...n]]
定義游標內可更新的列。如果提供了 OF column_name [,...n],則只允許修改列出的列。如果在 UPDATE 中未指定列的列表,除非指定了 READ_ONLY 并發(fā)選項,否則所有列均可更新。
注釋
DECLARE CURSOR 定義 Transact-SQL 服務(wù)器游標的特性,例如游標的滾動(dòng)行為和用于生成游標對其進(jìn)行操作的結果集的查詢(xún)。OPEN 語(yǔ)句填充結果集,FETCH 從結果集返回行。CLOSE 語(yǔ)句釋放與游標關(guān)聯(lián)的當前結果集。DEALLOCATE 語(yǔ)句釋放游標所使用的資源。
DECLARE CURSOR 語(yǔ)句的第一種格式使用 SQL-92 語(yǔ)法聲明游標行為。DECLARE CURSOR 的第二種格式使用 Transact-SQL 擴展,使您得以使用在 ODBC、ADO 和 DB-Library的數據庫 API 游標函數中的相同游標類(lèi)型定義游標。
不能混淆這兩種格式。如果在 CURSOR 關(guān)鍵字的前面指定 SCROLL 或 INSENSITIVE 關(guān)鍵字,則不能在 CURSOR 和 FOR select_statement 關(guān)鍵字之間使用任何關(guān)鍵字。如果在 CURSOR 和 FOR select_statement 關(guān)鍵字之間指定任何關(guān)鍵字,則不能在 CURSOR 關(guān)鍵字的前面指定 SCROLL 或 INSENSITIVE。
如果使用 Transact-SQL 語(yǔ)法的 DECLARE CURSOR 不指定 READ_ONLY、OPTIMISTIC 或 SCROLL_LOCKS,則默認設置如下:
如果 SELECT 語(yǔ)句不支持更新(權限不夠,訪(fǎng)問(wèn)的遠程表不支持更新,等等),則游標是 READ_ONLY。
STATIC 和FAST_FORWARD 游標默認為 READ_ONLY。
DYNAMIC 和 KEYSET 游標默認為 OPTIMISTIC。
游標名稱(chēng)只能由其它 Transact-SQL 語(yǔ)句引用,不能由數據庫 API 函數引用。例如,在聲明游標后,不能從 OLE DB、ODBC、ADO 或 DB-Library 函數或方法引用游標名稱(chēng)。游標行不能通過(guò) API 提取函數或方法提取,而只能由 Transact-SQL FETCH 語(yǔ)句提取。
在聲明游標后,可使用下列系統存儲過(guò)程確定游標的特性。
系統存儲過(guò)程 描述
sp_cursor_list 返回當前在連接上可視的游標列表及其特性。
sp_describe_cursor 描述游標特性,比如是只進(jìn)游標還是滾動(dòng)游標。
sp_describe_cursor_columns 描述游標結果集中的列的特性。
sp_describe_cursor_tables 描述游標所訪(fǎng)問(wèn)的基表。
變量可作為聲明游標的 select_statement 的一部分使用。然而,在游標聲明之后對那些變量的更改將不會(huì )對游標的操作產(chǎn)生影響。
權限
默認情況下,將 DECLARE CURSOR 權限授予對游標中所使用的視圖、表和列有 SELECT 權限的任何用戶(hù)。
示例
A. 使用簡(jiǎn)單游標和語(yǔ)法
打開(kāi)該游標時(shí)所生成的結果集包括 pubs 數據庫的 authors 表中的所有行和列??梢愿略撚螛?,對該游標所做的所有更新和刪除均在提取中表現出來(lái)。因為沒(méi)指定 SCROLL 選項,FETCH NEXT 是唯一可用的提取選項。
DECLARE authors_cursor CURSOR
FOR SELECT * FROM authors
OPEN authors_cursor
FETCH NEXT FROM authors_cursor
B. 使用嵌套游標生成報表輸出
下例顯示如何嵌套游標以生成復雜的報表。為每個(gè)作者聲明內部游標。
SET NOCOUNT ON
DECLARE @au_id varchar(11), @au_fname varchar(20), @au_lname varchar(40),
@message varchar(80), @title varchar(80)
PRINT "-------- Utah Authors report --------"
DECLARE authors_cursor CURSOR FOR
SELECT au_id, au_fname, au_lname
FROM authors
WHERE state = "UT"
ORDER BY au_id
OPEN authors_cursor
FETCH NEXT FROM authors_cursor
INTO @au_id, @au_fname, @au_lname
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT " "
SELECT @message = "----- Books by Author: " +
@au_fname + " " + @au_lname
PRINT @message
-- Declare an inner cursor based
-- on au_id from the outer cursor.
DECLARE titles_cursor CURSOR FOR
SELECT t.title
FROM titleauthor ta, titles t
WHERE ta.title_id = t.title_id AND
ta.au_id = @au_id -- Variable value from the outer cursor
OPEN titles_cursor
FETCH NEXT FROM titles_cursor INTO @title
IF @@FETCH_STATUS <> 0
PRINT " <<No Books>>"
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @message = " " + @title
PRINT @message
FETCH NEXT FROM titles_cursor INTO @title
END
CLOSE titles_cursor
DEALLOCATE titles_cursor
-- Get the next author.
FETCH NEXT FROM authors_cursor
INTO @au_id, @au_fname, @au_lname
END
CLOSE authors_cursor
DEALLOCATE authors_cursor
GO
-------- Utah Authors report --------
----- Books by Author: Anne Ringer
The Gourmet Microwave
Is Anger the Enemy?
----- Books by Author: Albert Ringer
Is Anger the Enemy?
Life Without Fear