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