每一個游標必須有四個組成部分這四個關鍵部分必須符合下面的順序;
1.DECLARE 游標
2.OPEN 游標
3.從一個游標中FETCH 信息
4.CLOSE 或DEALLOCATE 游標
通常我們使用DECLARE 來聲明一個游標聲明一個游標主要包括以下主要內容:
- 游標名字
- 數據來源(表和列)
- 選取條件
- 屬性(僅讀或可修改)
其語法格式如下:
DECLARE cursor_name [INSENSITIVE] [SCROLL] CURSOR
FOR select_statement
[FOR {READ ONLY | UPDATE [OF column_name [,...n]]}]
其中:
- cursor_name
指游標的名字。
- INSENSITIVE
表明MS SQL Server 會將游標定義所選取出來的數據記錄存放在一臨時表內(建立在tempdb 數據庫下)。對該游標的讀取操作皆由臨時表來應答。因此,對基本表的修改並不影響游標提取的數據,即游標不會隨著基本表內容的改變而改變,同時也無法通過
游標來更新基本表。如果不使用該保留字,那麼對基本表的更新、刪除都會反映到游標中。
另外應該指出,當遇到以下情況發生時,游標將自動設定INSENSITIVE 選項。
在SELECT 語句中使用DISTINCT、 GROUP BY、 HAVING UNION 語句;
使用OUTER JOIN;
所選取的任意表沒有索引;
將實數值當作選取的列。
- SCROLL
表明所有的提取操作(如FIRST、 LAST、 PRIOR、 NEXT、 RELATIVE、 ABSOLUTE)都可用。如果不使用該保留字,那麼只能進行NEXT 提取操作。由此可見,SCROLL 極大地增加了提取數據的靈活性,可以隨意讀取結果集中的任一行數據記錄,而不必關閉再
重開游標。
- select_statement
是定義結果集的SELECT 語句。應該注意的是,在游標中不能使用COMPUTE、COMPU- TE BY、 FOR BROWSE、 INTO 語句。
- READ ONLY
表明不允許游標內的數據被更新盡管在缺省狀態下游標是允許更新的。而且在UPDATE或DELETE 語句的WHERE CURRENT OF 子句中,不允許對該游標進行引用。
- UPDATE [OF column_name[,…n]]
定義在游標中可被修改的列,如果不指出要更新的列,那麼所有的列都將被更新。當游標被成功創建後,游標名成為該游標的惟一標識,如果在以後的存儲過程、觸發器或Transact_SQL 腳本中使用游標,必須指定該游標的名字。
上面介紹的是SQL_92 的游標語法規則。下面介紹MS SQL Server 提供的擴展了的游標聲明語法,通過增加另外的保留字,使游標的功能進一步得到了增強其語法規則為;
- LOCAL
定義游標的作用域僅限在其所在的存儲過程、觸發器或批處理中。當建立游標的存儲過程執行結束後,游標會被自動釋放。因此,我們常在存儲過程中使用OUTPUT 保留字,將游標傳遞給該存儲過程的調用者,這樣在存儲過程執行結束後,可以引用該游標變量,在該種情況下,直到引用該游標的最後一個就是被釋放時,游標才會自動釋放。
- GLOBAL
定義游標的作用域是整個會話層會話層指用戶的連接時間它包括從用戶登錄到SQLSERVER 到脫離數據庫的整段時間。選擇GLOBAL 表明在整個會話層的任何存儲過程、觸發器或批處理中都可以使用該游標,只有當用戶脫離數據庫、時該游標才會被自動釋放。
注意:如果既未使用GLOBAL也未使用LOCAL,那麼SQL Server將使用default local cursor數據庫選項,為了與以彰的版本歉容,該選項常設置為FALSE。
- FORWARD_ONLY
選項指明在從游標中提取數據記錄時,只能按照從第一行到最後一行的順序,此時只能選用FETCH NEXT 操作。除非使用STATIC, KEYSET 和DYNAMIC 關鍵字,否則如果未指明是使用FORWARD_ONLY 還是使用SCROLL, 那麼FORWARD_ONLY 將成為缺省選項,因為若使用STATIC KEYSET 和DYNAMIC 關鍵字,則變成了SCROLL 游標。另外如果使用了FORWARD_ONLY, 便不能使用FAST_FORWARD。
- STATIC
選項的含義與INSENSITIVE 選項一樣,MS SQL Server 會將游標定義所選取出來的數據記錄存放在一臨時表內(建立在tempdb 數據庫下)。對該游標的讀取操作皆由臨時表來應答。因此對基本表的修改並不影響游標中的數據,即游標不會隨著基本表內容的
改變而改變,同時也無法通過游標來更新基本表。
- KEYSET
指出當游標被打開時,游標中列的順序是固定的,並且MS SQL Server 會在tempdb內建立一個表,該表即為KEYSET KEYSET 的鍵值可惟一識別游標中的某行數據。當游標擁有者或其它用戶對基本表中的非鍵值數據進行修改時,這種變化能夠反映到游標中,所以游標用戶或所有者可以通過滾動游標提限這些數據。
當其它用戶增加一條新的符合所定義的游標范圍的數據時,無法由此游標讀到該數據。因為Transact-SQL 服務器游標不支持INSERT 語句。
如果在游標中的某一行被刪除掉,那麼當通過游標來提取該刪除行時,@@FETCH_STATUS 的返回值為-2。 @@FETCH_STATUS 是用來判斷讀取游標是否成功的系統全局變量。
由於更新操作包括兩部分:刪除原數據插入新數據,所以如果讀取原數據,@@FETCH_STATUS 的返回值為-2; 而且無法通過游標來讀取新插入的數據。但是如果使用了WHERE CURRENT OF 子句時,該新插入行數據便是可見的。
注意:如果基礎表未包含惟一的索引或主鍵,則一個KEYSET游標將回復成STATIC游標。
- DYNAMIC
指明基礎表的變化將反映到游標中,使用這個選項會最大程度上保證數據的一致性。然而,與KEYSET 和STATIC 類型游標相比較,此類型游標需要大量的游標資源。
- FAST_FORWARD
指明一個FORWARD_ONLY, READ_ONLY 型游標。此選項已為執行進行了優化。如果SCROLL 或FOR_UPDATE 選項被定義,則FAST_FORWARD 選項不能被定義。
- SCROLL_LOCKS
指明鎖被放置在游標結果集所使用的數據上當。數據被讀入游標中時,就會出現鎖。這個選項確保對一個游標進行的更新和刪除操作總能被成功執行。如果FAST_FORWARD選項被定義,則不能選擇該選項。另外,由於數據被游標鎖定,所以當考慮到數據並發處理時,應避免使用該選項。
- OPTIMISTIC
指明在數據被讀入游標後,如果游標中某行數據已發生變化,那麼對游標數據進行更新或刪除可能會導致失敗。如果使用了FAST_FORWARD 選項,則不能使用該選項。
- TYPE_WARNING
指明若游標類型被修改成與用戶定義的類型不同時,將發送一個警告信息給客戶端。
注意:不可以將SQL_92的游標語法規則與MS SQL Server的游標擴展用法混合在一起使用。
下面我們將總結一下聲明游標時應注意的一些問題。
如果在CURSOR 前使用了SCROLL 或INSENSITIVE 保留字,則不能在CURSOR 和FOR select_statement 之間使用任何的保留字。反之同理。
如果用DECLARE CURSOR 聲明游標時
您正在看的SQLserver教程是:SQL Server數據庫技術(82)。
,沒有選擇READ_ONLY、 OPTIMISTIC 或SCROLL_LOCKS 選項時,游標的缺省情況為:
如果SELECT 語句不支持更新,則游標為READ_ONLY;
STATIC 和FAST_FORWARD 類型的游標缺省為READ_ONLY;
DYNAMIC 和KEYSET 游標缺省為OPTIMISTIC。
我們僅能在Transact-SQL 語句中引用游標,而不能在數據庫API 函數中引用。
游標被聲明以後,可以通過系統過程對其特性進行設置。
對那些有權限對視圖、表或某些列執行SELECT 語句的用戶而言,它也具有使用游標的缺省權限。