遊標(Cursor)是處理資料的一種方法,為了查看或者處理結果集中的資料,遊標提供了在結果集中一次以行或者多行前進或向後瀏覽資料的能力。我們可以把遊標當作一個指標,它可以指定結果中的任何位置,然後允許使用者對指定位置的資料進行處理。
1.遊標的組成
遊標包含兩個部分:一個是遊標結果集、一個是遊標位置。
遊標結果集:定義該遊標得SELECT語句返回的行的集合。遊標位置:指向這個結果集某一行的當前指標。
2.遊標的分類
遊標共有3類:API伺服器資料指標、Transaction-SQL遊標和API用戶端資料指標。
其中前兩種遊標都是運行在伺服器上的,所以又叫做伺服器資料指標。
API伺服器資料指標
API伺服器資料指標主要應用在服務上,當用戶端的應用程式調用API遊標函數時,伺服器會對API函數進行處理。使用API函數和方法可以實現如下功能:
(1)開啟一個串連。
(2)設定定義遊標特徵的特性或屬性,API自動將遊標影射到每個結果集。
(3)執行一個或多個Transaction-SQL語句。
(4)使用API函數或方法提取結果集中的行。
API伺服器資料指標包含以下四種:靜態資料指標、動態資料指標、順向資料指標、鍵集驅動遊標(Primary key)
靜態資料指標的完整結果集將開啟遊標時建立的結果集儲存在暫存資料表中,(靜態資料指標始終是唯讀)。靜態資料指標具有以下特點:總是按照開啟遊標時的原樣顯示結果集;不反映資料庫中作的任何修改,也不反映對結果集行的列值所作的更改;不顯示開啟遊標後在資料庫中新插入的行;組成結果集的行被其他使用者更新,新的資料值不會顯示在靜態資料指標中;但是靜態資料指標會顯示開啟遊標以後從資料庫中刪除的行。
動態資料指標與靜態資料指標相反,當滾動遊標時動態資料指標反映結果集中的所有更改。結果集中的行資料值、順序和成員每次提取時都會改變。
順向資料指標不支援滾動,它只支援遊標從頭到尾順序提取資料行。注意:順向資料指標也反映對結果集所做的所有更改。
鍵集驅動遊標同時具有靜態資料指標和動態資料指標的特點。當開啟遊標時,該遊標中的成員以及行的順序是固定的,鍵集在遊標開啟時也會儲存到臨時工作表中,對非鍵集列的資料值的更改在使用者遊標滾動的時候可以看見,在遊標開啟以後對資料庫中插入的行是不可見的,除非關閉重新開啟遊標。
Transaction-SQL遊標
該遊標是基於Declare Cursor 文法,主要用於Transaction-SQL指令碼、預存程序以及觸發器中。Transaction-SQL遊標在伺服器處理由用戶端發送到伺服器的Transaction-SQL語句。
在預存程序或觸發器中使用Transaction-SQL遊標的過程為:
(1)聲明Transaction-SQL變數包含遊標返回的資料。為每個結果集列聲明一個變數。聲明足夠大的變數來儲存列返回的值,並聲明變數的類型為可從資料類型隱式轉換得到的資料類型。
(2)使用Declare Cursor語句將Transaction-SQL遊標與Select語句相關聯。還可以利用Declare Cursor定義遊標的唯讀、只進等特性。
(3)使用Open語句執行Select語句填充遊標。
(4)使用Fetch Into語句提取單個行,並將每列中得資料移至指定的變數中。注意:其他Transaction-SQL語句可以引用那些變數來訪問提取的資料值。Transaction-SQL遊標不支援提取行塊。
(5)使用Close語句結束遊標的使用。注意:關閉遊標以後,該遊標還是存在,可以使用Open命令開啟繼續使用,只有調用Deallocate語句才會完全釋放。
用戶端資料指標
該遊標將使用預設結果集把整個結果集快取在用戶端上,所有的遊標操作都在用戶端的快取中進行。注意:用戶端資料指標只支援只進和靜態資料指標。不支援其他遊標。
3.遊標的生命週期
遊標的生命週期包含有五個階段:聲明遊標、開啟遊標、讀取遊標資料、關閉遊標、釋放遊標。
聲明遊標是為遊標指定擷取資料時所使用的Select語句,聲明遊標並不會檢索任何資料,它只是為遊標指明了相應的Select 語句。
Declare 遊標名稱 Cursor 參數
聲明遊標的參數
(1)Local與Global:Local表示遊標的作用於僅僅限於其所在的預存程序、觸發器以及批處理中、執行完畢以後遊標自動釋放。Global表示的是該遊標範圍是整個會話層。由串連執行的任何預存程序、批處理等都可以引用該遊標名稱,僅在中斷連線時隱性釋放。
(2)Forward_only與Scroll:前者表示為順向資料指標,後者表示為可以隨意定位。預設為前者。
(3)Static、Keyset與Dynamic: 第一個表示定義一個遊標,其資料存放到一個暫存資料表內,對遊標的所有請求都從暫存資料表中應答,因此,對該遊標進行提取操作時返回的資料不反映對基表所作的修改,並且該遊標不允許修改。Keyset表示的是,當遊標開啟時,鍵集驅動遊標中行的身份與順序是固定的,並把其放到暫存資料表中。Dynamic表示的是滾動遊標時,動態資料指標反映對結果集內所有資料的更改。
(4)Read_only 、Scroll_Locks與Optimistic:第一個表示的是唯讀遊標,第二個表示的是在使用的遊標結果集資料上放置鎖,當行讀取到遊標中然後對它們進行修改時,資料庫將鎖定這些行,以保證資料的一致性。Optimistic的含義是遊標將資料讀取以後,如果這些資料被更新了,則通過遊標定位進行的更新與刪除操作將不會成功。
標準遊標:
Declare MyCursor Cursor
For Select * From Master_Goods
唯讀遊標
Declare MyCusror Cursor
For Select * From Master_Goods
For Read Only
可更新遊標
Declare MyCusror Cursor
For Select * From Master_Goods
For UpDate
開啟遊標使用Open語句用於開啟Transaction-SQL伺服器資料指標,執行Open語句的過程中就是按照Select語句進行填充資料,開啟遊標以後遊標位置在第一行。
開啟遊標
全域遊標:Open Global MyCursor 局部遊標: Open MyCursor
讀取遊標資料:在開啟遊標以後,使用Fetch語句從Transaction-SQL伺服器資料指標中檢索特定的一行。使用Fetch操作,可以使遊標移動到下一個記錄,並將遊標返回的每個列得資料分別賦值給聲明的本地變數。
Fetch [Next | Prior | First | Last | Absolute n | Relative n ] From MyCursor
Into @GoodsID,@GoodsName
其中:Next表示返回結果集中當前行的下一行記錄,如果第一次讀取則返回第一行。預設的讀取選項為Next
Prior表示返回結果集中當前行的前一行記錄,如果第一次讀取則沒有行返回,並且把遊標置於第一行之前。
First表示返回結果集中的第一行,並且將其作為當前行。
Last表示返回結果集中的最後一行,並且將其作為當前行。
Absolute n 如果n為正數,則返回從遊標題開始的第n行,並且返回行變成新的當前行。如果n為負,則返回從遊標末尾開始的第n行,並且返回行為新的當前行,如果n為0,則返回當前行。
Relative n 如果n為正數,則返回從當前行開始的第n行,如果n為負,則返回從當前行之前的第n行,如果為0,則返回當前行。
關閉遊標調用的是Close語句,方式如下:Close Global MyCursor Close MyCursor
釋放遊標調用的是Deallocate語句,方法如下:Deallocate Glboal MyCursor Deallocate MyCursor
遊標執行個體:
Declare MyCusror Cursor Scroll
For Select * From Master_Goods Order By GoodsID
Open MyCursor
Fetch next From MyCursor
Into @GoodsCode,@GoodsName
While(@@Fetch_Status = 0)
Begin
Begin
Select @GoodsCode = Convert(Char(20),@GoodsCode)
Select @GoodsName = Convert(Char(20),@GoodsName)
PRINT @GoodsCode + ':' + @GoodsName
End
Fetch next From MyCursor
Into @GoodsCode,@GoodsName
End
Close MyCursor
Deallocate MyCursor
修改當前遊標的資料方法如下:
UpDate Master_Goods Set GoodsName = 'yangyang8848' Where Current Of MyCursor;
刪除當前遊標行資料的方法如下:
Delete From Master_Goods Where Current Of MyCursor
Select @@CURSOR_ROWS 可以得到當前遊標中存在的資料行數。注意:此變數為一個串連上的全域變數,因此只對應最後一次開啟的遊標。