姚曦
(福建衛生職業技術學院公共基礎部,福建 福州 350101)
在數據庫的使用中,常常會遇到這種情況:用查詢語句,得到一個結果集,但對這個結果的操作不是相同的,需要根據不同的條件,對不同的記錄進行不同的處理。此時,就需要用到游標。
游標實際上是一種能從包括多條記錄的結果集中每次提取一條記錄的機制。游標總是與一條SQL查詢語句相關聯,允許應用程序對SELECT語句返回的行結果集中每一行進行相同或不同的操作,而不是一次對整個結果集進行同一種操作。這種特性使得對數據的操縱十分靈活。
SQL支持三種類型的游標:Transact-SQL游標、API游標和客戶游標。
Transact-SQL游標:T-SQL游標是由DECLARE CURSOR語句定義,主要用在腳本、存儲過程和觸發器中,應用在服務器上。
API游標:API游標使用在客戶端與服務器端的連接程序中(如OLE DB和ODBC等)。
客戶游標:客戶游標主要在當需要在客戶機上緩存結果集時使用。
游標的操作可分為以下幾個步驟:
聲明游標的語法為:
DECLARE<游標名>[INSENSITIVE][SCROLL]CURSOR
FOR<SELECT語句>
[FOR{READ ONLY|UPDATE][OF<列名>[,…n]]}]
INSENSITIVE關鍵字:將取出的數據記錄放在一個臨時表內,對游標的讀取操作由臨時表來應答。游標不會隨著基表內容的改變而改變,同時也無法通過游標來更新基本表。
SCROLL關鍵字:表明所有的提取操作(FIRST,LAST,PRIOR,NEXT,RELATIVE,ABSOLUTE)等都可用,如不使用該保留字,只能進行NEXT操作。
READ ONLY關鍵字:只讀游標。
UPDATE關鍵字:可修改的游標,或指定修改的列。
聲明游標后,如果要從游標中讀取數據,必須打開游標。
打開游標的語法為:
OPEN[GLOBAL]<游標名>│<游標變量>
在游標成功打開后,全局變量@@CURSOR_ROWS將用來記錄游標內數據行數。變量返回值代表的狀態如表1所示。

表1 @@CURSOR_ROWS變量的返回值
當游標成功打開以后,可以使用FETCH語句從中讀取數據。

{{GLOBAL<游標名>}│<@游標變量>}
[INTO@<變量名>[,…n]]
NEXT│PRIOR│FIRST│LAST:用于說明讀取數據的位置。
ABSOLUTE、RELATIVE:給出讀取數據的位置與游標頭或當前位置的關系。其中N必須為整型常量或變量。
其中全局變量@@FETCH_STATUS返回上次執行FETCH命令的狀態。在每次用FETCH從游標中讀取數據時,都應檢查該變量,以確定上次FETCH操作是否成功,來決定如何進行下一步處理。變量的返回值的狀態如表2所示。

表2 @@FETCH_STATUS的返回值
CLOSE[GLOBAL]<游標名>|@<游標變量>
游標關閉后,其定義仍在,需要時可用OPEN語句打開,再次使用。若確認游標不再需要,就要釋放其定義占用的系統空間,即刪除游標。
DEALLOCATE[GLOBAL]<游標名>|@<游標變量>
案例說明:數據庫company中有兩張表。Salary顯示的是全體員工的工資表,工作一段時間后,公司將按照員工的工作情況給員工加工資,每個員工加的工資不一樣多,有的員工工資有調整,有的員工工資無調整。工資調整表為addincome。這種不是統一變動的情況,使用游標就非常靈活便捷。
游標使用的具體代碼如下:
select*from salary
declare@id char(10),@salary int
declare sa_cur1 cursor

以上代碼說明:首先基于salary表生成一個更新游標的結果集。從中逐條讀取id參數,將id參數存放在@id變量中。使用@id變量在addincome表中查詢是否有此@id員工,如果有此@id就表明,此@id的工資有調整,使用更新游標將調整的工資更新到salary表。如果無此@id就說明此@id的工資無調整,回到游標結果集中讀取下一條記錄。
本文介紹了SQL數據庫中游標的概念,闡述了游標的類型及游標的使用步驟。最后通過一個更新工資表的實例說明游標的使用方法。
[1]李丹.SQL Server2005數據庫管理與開發實用教程[M].北京:機械工業出版社,2010.
[2]申時凱,戴祖誠,佘玉梅.數據庫原理與技術[M].北京:清華大學出版社,2010.