一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

SQL Server游標(biāo)

 lvyafei 2012-04-13
游標(biāo)和游標(biāo)的優(yōu)點(diǎn)
    在數(shù)據(jù)庫(kù)中,游標(biāo)是一個(gè)十分重要的概念。游標(biāo)提供了一種對(duì)從表中檢索出的數(shù)據(jù)進(jìn)行操作的靈活手段,就本質(zhì)而言,游標(biāo)實(shí)際上是一種能從包括多條數(shù)據(jù)記錄的結(jié)果集中每次提取一條記錄的機(jī)制。游標(biāo)總是與一條T_SQL 選擇語(yǔ)句相關(guān)聯(lián)因?yàn)橛螛?biāo)由結(jié)果集(可以是零條、一條或由相關(guān)的選擇語(yǔ)句檢索出的多條記錄)和結(jié)果集中指向特定記錄的游標(biāo)位置組成。當(dāng)決定對(duì)結(jié)果集進(jìn)行處理時(shí),必須聲明一個(gè)指向該結(jié)果集的游標(biāo)。如果曾經(jīng)用 C 語(yǔ)言寫(xiě)過(guò)對(duì)文件進(jìn)行處理的程序,那么游標(biāo)就像您打開(kāi)文件所得到的文件句柄一樣,只要文件打開(kāi)成功,該文件句柄就可代表該文件。對(duì)于游標(biāo)而言,其道理是相同的??梢?jiàn)游標(biāo)能夠?qū)崿F(xiàn)按與傳統(tǒng)程序讀取平面文件類似的方式處理來(lái)自基礎(chǔ)表的結(jié)果集,從而把表中數(shù)據(jù)以平面文件的形式呈現(xiàn)給程序。
    我們知道關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)實(shí)質(zhì)是面向集合的,在MS SQL SERVER 中并沒(méi)有一種描述表中單一記錄的表達(dá)形式,除非使用where 子句來(lái)限制只有一條記錄被選中。因此我們必須借助于游標(biāo)來(lái)進(jìn)行面向單條記錄的數(shù)據(jù)處理。
    由此可見(jiàn),游標(biāo)允許應(yīng)用程序?qū)Σ樵冋Z(yǔ)句select 返回的行結(jié)果集中每一行進(jìn)行相同或不同的操作,而不是一次對(duì)整個(gè)結(jié)果集進(jìn)行同一種操作;它還提供對(duì)基于游標(biāo)位置而對(duì)表中數(shù)據(jù)進(jìn)行刪除或更新的能力;而且,正是游標(biāo)把作為面向集合的數(shù)據(jù)庫(kù)管理系統(tǒng)和面向行的程序設(shè)計(jì)兩者聯(lián)系起來(lái),使兩個(gè)數(shù)據(jù)處理方式能夠進(jìn)行溝通。
游標(biāo)種類及用法
    SQL SERVER 支持三種類型的游標(biāo):Transact_SQL 游標(biāo),API 服務(wù)器游標(biāo)和客戶游標(biāo)。
   (1)Transact_SQL 游標(biāo)
    Transact_SQL 游標(biāo)是由DECLARE CURSOR 語(yǔ)法定義、主要用在Transact_SQL 腳本、存儲(chǔ)過(guò)程和觸發(fā)器中。Transact_SQL 游標(biāo)主要用在服務(wù)器上,由從客戶端發(fā)送給服務(wù)器的Transact_SQL 語(yǔ)句或是批處理、存儲(chǔ)過(guò)程、觸發(fā)器中的Transact_SQL 進(jìn)行管理。 Transact_SQL 游標(biāo)不支持提取數(shù)據(jù)塊或多行數(shù)據(jù)。
   (2)API 游標(biāo)
    API 游標(biāo)支持在OLE DB, ODBC 以及DB_library 中使用游標(biāo)函數(shù),主要用在服務(wù)器上。每一次客戶端應(yīng)用程序調(diào)用API 游標(biāo)函數(shù),MS SQL SEVER 的OLE DB 提供者、ODBC驅(qū)動(dòng)器或DB_library 的動(dòng)態(tài)鏈接庫(kù)(DLL) 都會(huì)將這些客戶請(qǐng)求傳送給服務(wù)器以對(duì)API游標(biāo)進(jìn)行處理。
   (3)客戶游標(biāo)
    客戶游標(biāo)主要是當(dāng)在客戶機(jī)上緩存結(jié)果集時(shí)才使用。在客戶游標(biāo)中,有一個(gè)缺省的結(jié)果集被用來(lái)在客戶機(jī)上緩存整個(gè)結(jié)果集??蛻粲螛?biāo)僅支持靜態(tài)游標(biāo)而非動(dòng)態(tài)游標(biāo)。由于服務(wù)器游標(biāo)并不支持所有的Transact-SQL 語(yǔ)句或批處理,所以客戶游標(biāo)常常僅被用作服務(wù)器游標(biāo)的輔助。因?yàn)樵谝话闱闆r下,服務(wù)器游標(biāo)能支持絕大多數(shù)的游標(biāo)操作。
    由于API 游標(biāo)和Transact-SQL 游標(biāo)使用在服務(wù)器端,所以被稱為服務(wù)器游標(biāo),也被稱為后臺(tái)游標(biāo),而客戶端游標(biāo)被稱為前臺(tái)游標(biāo)。在本章中我們主要講述服務(wù)器(后臺(tái))游標(biāo)。
    每一個(gè)游標(biāo)必須有四個(gè)組成部分這四個(gè)關(guān)鍵部分必須符合下面的順序;
    1.DECLARE 游標(biāo)
    2.OPEN 游標(biāo)
    3.從一個(gè)游標(biāo)中FETCH 信息
    4.CLOSE 或DEALLOCATE 游標(biāo)
    通常我們使用DECLARE 來(lái)聲明一個(gè)游標(biāo)聲明一個(gè)游標(biāo)主要包括以下主要內(nèi)容:
    游標(biāo)名字
    數(shù)據(jù)來(lái)源(表和列)
    選取條件
    屬性(僅讀或可修改)
    其語(yǔ)法格式如下:
    DECLARE cursor_name [INSENSITIVE] [SCROLL] CURSOR
    FOR select_statement
    [FOR {READ ONLY | UPDATE [OF column_name [,...n]]}]
    其中:
    cursor_name
    指游標(biāo)的名字。
    INSENSITIVE
    表明MS SQL SERVER 會(huì)將游標(biāo)定義所選取出來(lái)的數(shù)據(jù)記錄存放在一臨時(shí)表內(nèi)(建立在tempdb 數(shù)據(jù)庫(kù)下)。對(duì)該游標(biāo)的讀取操作皆由臨時(shí)表來(lái)應(yīng)答。因此,對(duì)基本表的修改并不影響游標(biāo)提取的數(shù)據(jù),即游標(biāo)不會(huì)隨著基本表內(nèi)容的改變而改變,同時(shí)也無(wú)法通過(guò)游標(biāo)來(lái)更新基本表。如果不使用該保留字,那么對(duì)基本表的更新、刪除都會(huì)反映到游標(biāo)中。
    另外應(yīng)該指出,當(dāng)遇到以下情況發(fā)生時(shí),游標(biāo)將自動(dòng)設(shè)定INSENSITIVE 選項(xiàng)。
    在SELECT 語(yǔ)句中使用DISTINCT、 GROUP BY、 HAVING UNION 語(yǔ)句;
    使用OUTER JOIN;
    所選取的任意表沒(méi)有索引;
    將實(shí)數(shù)值當(dāng)作選取的列。
    SCROLL
    表明所有的提取操作(如FIRST、 LAST、 PRIOR、 NEXT、 RELATIVE、 ABSOLUTE)都可用。如果不使用該保留字,那么只能進(jìn)行NEXT 提取操作。由此可見(jiàn),SCROLL 極大地增加了提取數(shù)據(jù)的靈活性,可以隨意讀取結(jié)果集中的任一行數(shù)據(jù)記錄,而不必關(guān)閉再重開(kāi)游標(biāo)。
    select_statement是定義結(jié)果集的SELECT 語(yǔ)句。應(yīng)該注意的是,在游標(biāo)中不能使用COMPUTE、COMPU- TE BY、 FOR BROWSE、INTO 語(yǔ)句。
    READ ONLY表明不允許游標(biāo)內(nèi)的數(shù)據(jù)被更新盡管在缺省狀態(tài)下游標(biāo)是允許更新的。而且在UPDATE或DELETE 語(yǔ)句的WHERE CURRENT OF 子句中,不允許對(duì)該游標(biāo)進(jìn)行引用。
    UPDATE [OF column_name[,…n]]
    定義在游標(biāo)中可被修改的列,如果不指出要更新的列,那么所有的列都將被更新。當(dāng)游標(biāo)被成功創(chuàng)建后,游標(biāo)名成為該游標(biāo)的惟一標(biāo)識(shí),如果在以后的存儲(chǔ)過(guò)程、觸發(fā)器或Transact_SQL 腳本中使用游標(biāo),必須指定該游標(biāo)的名字。
    上面介紹的是SQL_92 的游標(biāo)語(yǔ)法規(guī)則。下面介紹MS SQL SERVER 提供的擴(kuò)展了的游標(biāo)聲明語(yǔ)法,通過(guò)增加另外的保留字,使游標(biāo)的功能進(jìn)一步得到了增強(qiáng)其語(yǔ)法規(guī)則為;
    LOCAL
    定義游標(biāo)的作用域僅限在其所在的存儲(chǔ)過(guò)程、觸發(fā)器或批處理中。當(dāng)建立游標(biāo)的存儲(chǔ)過(guò)程執(zhí)行結(jié)束后,游標(biāo)會(huì)被自動(dòng)釋放。因此,我們常在存儲(chǔ)過(guò)程中使用OUTPUT 保留字,將游標(biāo)傳遞給該存儲(chǔ)過(guò)程的調(diào)用者,這樣在存儲(chǔ)過(guò)程執(zhí)行結(jié)束后,可以引用該游標(biāo)變量,在該種情況下,直到引用該游標(biāo)的最后一個(gè)就是被釋放時(shí),游標(biāo)才會(huì)自動(dòng)釋放。
    GLOBAL
    定義游標(biāo)的作用域是整個(gè)會(huì)話層會(huì)話層指用戶的連接時(shí)間它包括從用戶登錄到SQLSERVER 到脫離數(shù)據(jù)庫(kù)的整段時(shí)間。選擇GLOBAL 表明在整個(gè)會(huì)話層的任何存儲(chǔ)過(guò)程、觸發(fā)器或批處理中都可以使用該游標(biāo),只有當(dāng)用戶脫離數(shù)據(jù)庫(kù)、時(shí)該游標(biāo)才會(huì)被自動(dòng)釋放。
    注意:如果既未使用GLOBAL也未使用LOCAL,那么SQL SERVER將使用default local cursor數(shù)據(jù)庫(kù)選項(xiàng),為了與以彰的版本歉容,該選項(xiàng)常設(shè)置為FALSE。
    FORWARD_ONLY
    選項(xiàng)指明在從游標(biāo)中提取數(shù)據(jù)記錄時(shí),只能按照從第一行到最后一行的順序,此時(shí)只能選用FETCH NEXT 操作。除非使用STATIC, KEYSET 和DYNAMIC 關(guān)鍵字,否則如果未指明是使用FORWARD_ONLY 還是使用SCROLL, 那么FORWARD_ONLY 將成為缺省選項(xiàng),因?yàn)槿羰褂肧TATIC KEYSET 和DYNAMIC 關(guān)鍵字,則變成了SCROLL 游標(biāo)。另外如果使用了FORWARD_ONLY, 便不能使用FAST_FORWARD。
    STATIC
    選項(xiàng)的含義與INSENSITIVE 選項(xiàng)一樣,MS SQL SERVER 會(huì)將游標(biāo)定義所選取出來(lái)的數(shù)據(jù)記錄存放在一臨時(shí)表內(nèi)(建立在tempdb 數(shù)據(jù)庫(kù)下)。對(duì)該游標(biāo)的讀取操作皆由臨時(shí)表來(lái)應(yīng)答。因此對(duì)基本表的修改并不影響游標(biāo)中的數(shù)據(jù),即游標(biāo)不會(huì)隨著基本表內(nèi)容的改變而改變,同時(shí)也無(wú)法通過(guò)游標(biāo)來(lái)更新基本表。
    KEYSET
    指出當(dāng)游標(biāo)被打開(kāi)時(shí),游標(biāo)中列的順序是固定的,并且MS SQL SERVER 會(huì)在tempdb內(nèi)建立一個(gè)表,該表即為KEYSET KEYSET 的鍵值可惟一識(shí)別游標(biāo)中的某行數(shù)據(jù)。當(dāng)游標(biāo)擁有者或其它用戶對(duì)基本表中的非鍵值數(shù)據(jù)進(jìn)行修改時(shí),這種變化能夠反映到游標(biāo)中,所以游標(biāo)用戶或所有者可以通過(guò)滾動(dòng)游標(biāo)提限這些數(shù)據(jù)。
    當(dāng)其它用戶增加一條新的符合所定義的游標(biāo)范圍的數(shù)據(jù)時(shí),無(wú)法由此游標(biāo)讀到該數(shù)據(jù)。因?yàn)門ransact-SQL 服務(wù)器游標(biāo)不支持INSERT 語(yǔ)句。
    如果在游標(biāo)中的某一行被刪除掉,那么當(dāng)通過(guò)游標(biāo)來(lái)提取該刪除行時(shí),@@FETCH_STATUS 的返回值為-2。 @@FETCH_STATUS 是用來(lái)判斷讀取游標(biāo)是否成功的系統(tǒng)全局變量。
    由于更新操作包括兩部分:刪除原數(shù)據(jù)插入新數(shù)據(jù),所以如果讀取原數(shù)據(jù),@@FETCH_STATUS 的返回值為-2; 而且無(wú)法通過(guò)游標(biāo)來(lái)讀取新插入的數(shù)據(jù)。但是如果使用了WHERE CURRENT OF 子句時(shí),該新插入行數(shù)據(jù)便是可見(jiàn)的。
注意:如果基礎(chǔ)表未包含惟一的索引或主鍵,則一個(gè)KEYSET游標(biāo)將回復(fù)成STATIC游標(biāo)。
    DYNAMIC
    指明基礎(chǔ)表的變化將反映到游標(biāo)中,使用這個(gè)選項(xiàng)會(huì)最大程度上保證數(shù)據(jù)的一致性。然而,與KEYSET 和STATIC 類型游標(biāo)相比較,此類型游標(biāo)需要大量的游標(biāo)資源。
    FAST_FORWARD
    指明一個(gè)FORWARD_ONLY, READ_ONLY 型游標(biāo)。此選項(xiàng)已為執(zhí)行進(jìn)行了優(yōu)化。如果SCROLL 或FOR_UPDATE 選項(xiàng)被定義,則FAST_FORWARD 選項(xiàng)不能被定義。
    SCROLL_LOCKS
    指明鎖被放置在游標(biāo)結(jié)果集所使用的數(shù)據(jù)上當(dāng)。數(shù)據(jù)被讀入游標(biāo)中時(shí),就會(huì)出現(xiàn)鎖。這個(gè)選項(xiàng)確保對(duì)一個(gè)游標(biāo)進(jìn)行的更新和刪除操作總能被成功執(zhí)行。如果FAST_FORWARD選項(xiàng)被定義,則不能選擇該選項(xiàng)。另外,由于數(shù)據(jù)被游標(biāo)鎖定,所以當(dāng)考慮到數(shù)據(jù)并發(fā)處理時(shí),應(yīng)避免使用該選項(xiàng)。
    OPTIMISTIC
    指明在數(shù)據(jù)被讀入游標(biāo)后,如果游標(biāo)中某行數(shù)據(jù)已發(fā)生變化,那么對(duì)游標(biāo)數(shù)據(jù)進(jìn)行更新或刪除可能會(huì)導(dǎo)致失敗。如果使用了FAST_FORWARD 選項(xiàng),則不能使用該選項(xiàng)。
    TYPE_WARNING
    指明若游標(biāo)類型被修改成與用戶定義的類型不同時(shí),將發(fā)送一個(gè)警告信息給客戶端。
    注意:不可以將SQL_92的游標(biāo)語(yǔ)法規(guī)則與MS SQL SERVER的游標(biāo)擴(kuò)展用法混合在一起使用。
    下面我們將總結(jié)一下聲明游標(biāo)時(shí)應(yīng)注意的一些問(wèn)題。
    如果在CURSOR 前使用了SCROLL 或INSENSITIVE 保留字,則不能在CURSOR 和FOR select_statement 之間使用任何的保留字。反之同理。
    如果用DECLARE CURSOR 聲明游標(biāo)時(shí),沒(méi)有選擇READ_ONLY、 OPTIMISTIC 或SCROLL_LOCKS 選項(xiàng)時(shí),游標(biāo)的缺省情況為:
    如果SELECT 語(yǔ)句不支持更新,則游標(biāo)為READ_ONLY;
    STATIC 和FAST_FORWARD 類型的游標(biāo)缺省為READ_ONLY;  
    DYNAMIC 和KEYSET 游標(biāo)缺省為OPTIMISTIC。
    我們僅能在Transact-SQL 語(yǔ)句中引用游標(biāo),而不能在數(shù)據(jù)庫(kù)API 函數(shù)中引用。
    游標(biāo)被聲明以后,可以通過(guò)系統(tǒng)過(guò)程對(duì)其特性進(jìn)行設(shè)置。
    對(duì)那些有權(quán)限對(duì)視圖、表或某些列執(zhí)行SELECT 語(yǔ)句的用戶而言,它也具有使用游標(biāo)的缺省權(quán)限。
    打開(kāi)游標(biāo)游標(biāo)在聲明以后,如果要從游標(biāo)中讀取數(shù)據(jù)必須打開(kāi)游標(biāo)。打開(kāi)一個(gè)Transact-SQL服務(wù)器游標(biāo)使用OPEN 命令,其語(yǔ)法規(guī)則為:
    OPEN { { [GLOBAL] cursor_name } | cursor_variable_name}
各參數(shù)說(shuō)明如下:
    GLOBAL
    定義游標(biāo)為一全局游標(biāo)。
    cursor_name
    為聲明的游標(biāo)名字。如果一個(gè)全局游標(biāo)和一個(gè)局部游標(biāo)都使用同一個(gè)游標(biāo)名,則如果使用GLOBAL 便表明其為全局游標(biāo),否則表明其為局部游標(biāo)。
    cursor_variable_name
    為游標(biāo)變量。當(dāng)打開(kāi)一個(gè)游標(biāo)后時(shí),MS SQL SERVER 首先檢查聲明游標(biāo)的語(yǔ)法是否正確,如果游標(biāo)聲明中有變量,則將變量值帶入。
    在打開(kāi)游標(biāo)時(shí),如果游標(biāo)聲明語(yǔ)句中使用了INSENSITIVE 或STATIC 保留字,則OPEN產(chǎn)生一個(gè)臨時(shí)表來(lái)存放結(jié)果集;如果在結(jié)果集中任何一行數(shù)據(jù)的大小超過(guò)MS SQL SERVER定義的最大行尺寸時(shí),OPEN 命令將失??;如果聲明游標(biāo)時(shí)作用了KEYSET 選項(xiàng),則OPEN 產(chǎn)生一個(gè)臨時(shí)表來(lái)存放鍵值。所有的臨時(shí)表都存在tempdb 數(shù)據(jù)庫(kù)中。
    在游標(biāo)被成功打開(kāi)之后,@@CURSOR_ROWS 全局變量將用來(lái)記錄游標(biāo)內(nèi)數(shù)據(jù)行數(shù)。為了提高性能,MS SQL SERVER 允許以異步方式從基礎(chǔ)表向KEYSET 或靜態(tài)游標(biāo)讀入數(shù)據(jù),即如果MS SQL SERVER 的查詢優(yōu)化器估計(jì)從基礎(chǔ)表中返回給游標(biāo)的數(shù)據(jù)行已經(jīng)超過(guò)sp_configure cursor threshold 參數(shù)值,則MS SQL SERVER 將啟動(dòng)另外一個(gè)獨(dú)立的線程來(lái)繼續(xù)從基礎(chǔ)表中讀入符合游標(biāo)定義的數(shù)據(jù)行,此時(shí)可以從游標(biāo)。中讀取數(shù)據(jù)進(jìn)行處理而不必等到所有的符合游標(biāo)定義的數(shù)據(jù)行都從基礎(chǔ)表中讀入游標(biāo) @@CURSOR_ROWS 變量存儲(chǔ)的正是在調(diào)用@@CURSOR_ROWS 時(shí),游標(biāo)已從基礎(chǔ)表讀入的數(shù)據(jù)行。@@CURSOR_ROWS 的返回值有以下四個(gè),如表13-1 所示。
    如果所打開(kāi)的游標(biāo)在聲明時(shí)帶有SCROLL 或INSENSITIVE 保留字,那么@@CURSOR_ROWS 的值為正數(shù)且為該游標(biāo)的所有數(shù)據(jù)行。如果未加上這兩個(gè)保留字中的一個(gè),則@@CURSOR_ROWS 的值為-1, 說(shuō)明該游標(biāo)內(nèi)只有一條數(shù)據(jù)記錄。
    當(dāng)游標(biāo)被成功打開(kāi)以后,就可以從游標(biāo)中逐行地讀取數(shù)據(jù),以進(jìn)行相關(guān)處理。從游標(biāo)中讀取數(shù)據(jù)主要使用FETCH 命令。其語(yǔ)法規(guī)則為:
    各參數(shù)含義說(shuō)明如下:
    NEXT
    返回結(jié)果集中當(dāng)前行的下一行,并增加當(dāng)前行數(shù)為返回行行數(shù)。如果FETCH NEXT是第一次讀取游標(biāo)中數(shù)據(jù),則返回結(jié)果集中的是第一行而不是第二行。
    PRIOR
    返回結(jié)果集中當(dāng)前行的前一行,并減少當(dāng)前行數(shù)為返回行行數(shù)。如果FETCH PRIOR是第一次讀取游標(biāo)中數(shù)據(jù),則無(wú)數(shù)據(jù)記錄返回,并把游標(biāo)位置設(shè)為第一行。
    FIRST
    返回游標(biāo)中第一行。
    LAST
    返回游標(biāo)中的最后一行。
    ABSOLUTE {n | @nvar}
    如果n 或@nvar 為正數(shù),則表示從游標(biāo)中返回的數(shù)據(jù)行數(shù)。如果n 或@nvar 為負(fù)數(shù),則返回游標(biāo)內(nèi)從最后一行數(shù)據(jù)算起的第n 或@nvar 行數(shù)據(jù)。若n 或@nvar 超過(guò)游標(biāo)的數(shù)據(jù)子集范疇,則@@FETCH_STARS 返回-1, 在該情況下,如果n 或@nvar 為負(fù)數(shù),則執(zhí)行FETCH NEXT 命令會(huì)得到第一行數(shù)據(jù),如果n 或@nvar為正值,執(zhí)行FETCH PRIOR 命令則會(huì)得到最后一行數(shù)據(jù)。n 或@nvar 可以是一固定值也可以是一smallint, tinyint 或int 類型的變量。
    RELATIVE {n | @nvar}
    若n 或@nvar 為正數(shù),則讀取游標(biāo)當(dāng)前位置起向后的第n 或@nvar 行數(shù)據(jù);如果n 或@nvar 為負(fù)數(shù),則讀取游標(biāo)當(dāng)前位置起向前的第n 或@nvar 行數(shù)據(jù)。若n 或@nvar 超過(guò)游標(biāo)的數(shù)據(jù)子集范疇,則@@FETCH_STARS 返回-1, 在該情況下,如果n 或@nvar 為負(fù)數(shù),則執(zhí)行FETCH NEXT 命令則會(huì)得到第一行數(shù)據(jù);如果n 或@nvar 為正值,執(zhí)行FETCH PRIOR 命令則會(huì)得到最后一行數(shù)據(jù)。n 或@nvar 可以是一固定值也可以是一smallint, tinyint或int 類型的變量。
    INTO @variable_name[,...n]
    允許將使用FETCH 命令讀取的數(shù)據(jù)存放在多個(gè)變量中。在變量行中的每個(gè)變量必須與游標(biāo)結(jié)果集中相應(yīng)的列相對(duì)應(yīng),每一變量的數(shù)據(jù)類型也要與游標(biāo)中數(shù)據(jù)列的數(shù)據(jù)類型相匹配。
    @@FETCH_STATUS 全局變量返回上次執(zhí)行FETCH 命令的狀態(tài)。在每次用FETCH從游標(biāo)中讀取數(shù)據(jù)時(shí),都應(yīng)檢查該變量,以確定上次FETCH 操作是否成功,來(lái)決定如何進(jìn)行下一步處理。@@FETCH_STATUS 變量有三個(gè)不同的返回值,如表13-2。
    在使用FETCH 命令從游標(biāo)中讀取數(shù)據(jù)時(shí),應(yīng)該注意以下的情況:
    當(dāng)使用SQL-92 語(yǔ)法來(lái)聲明一個(gè)游標(biāo)時(shí),沒(méi)有選擇SCROLL 選項(xiàng)時(shí),只能使用FETCH NEXT 命令來(lái)從游標(biāo)中讀取數(shù)據(jù),即只能從結(jié)果集第一行按順序地每次讀取一行,由于不能使用FIRST、 LAST、 PRIOR, 所以無(wú)法回滾讀取以前的數(shù)據(jù)。如果選擇了SCROLL 選項(xiàng),則可能使用所有的FETCH 操作。
    當(dāng)使用MS SQL SERVER 的擴(kuò)展語(yǔ)法時(shí),必須注意以下約定:
    如果定義了FORWARD-ONLY 或FAST_FORWARD 選項(xiàng),則只能使用FETCH NEXT命令;
如果沒(méi)有定義DYNAMIC, FORWARD_ONLY 或FAST_FORWARD 選項(xiàng),而定義了KEYSET, STATIC 或SCROLL 中的任何一個(gè),則可使用所有的FETCH 操作;DYNAMIC SCROLL 游標(biāo)支持所有的FETCH, 選項(xiàng)但禁用ABSOLUTE 選項(xiàng)。
    關(guān)閉游標(biāo)
    1、使用CLOSE 命令關(guān)閉游標(biāo)
    在處理完游標(biāo)中數(shù)據(jù)之后必須關(guān)閉游標(biāo)來(lái)釋放數(shù)據(jù)結(jié)果集和定位于數(shù)據(jù)記錄上的鎖。CLOSE 語(yǔ)句關(guān)閉游標(biāo),但不釋放游標(biāo)占用的數(shù)據(jù)結(jié)構(gòu)。如果準(zhǔn)備在隨后的使用中再次打開(kāi)游標(biāo),則應(yīng)使用CLOSE 命令。其關(guān)閉游標(biāo)的語(yǔ)法規(guī)則為:
    CLOSE { { [GLOBAL] cursor_name } | cursor_variable_name }
    2、自動(dòng)關(guān)閉游標(biāo)
    我們已經(jīng)了解到游標(biāo)可應(yīng)用在存儲(chǔ)過(guò)程、觸發(fā)器和Transact_SQL腳本中。如果在聲明游標(biāo)與釋放游標(biāo)之間使用了事務(wù)結(jié)構(gòu),則在結(jié)束事務(wù)時(shí)游標(biāo)會(huì)自動(dòng)關(guān)閉。其具體的情況如下所示:
    (1)、聲明一個(gè)游標(biāo)
    (2)、打開(kāi)游標(biāo)
    (3)、讀取游標(biāo)
    (4)、BEGIN TRANSATION
    (5)、數(shù)據(jù)處理
    (6)、COMMIT TRANSATION
    (7)、回到步驟3
    在這樣的應(yīng)用環(huán)境中。當(dāng)從游標(biāo)中讀取一條數(shù)據(jù)記錄進(jìn)行以BEGIN TRANSATION為開(kāi)頭,COMMIT TRANSATION 或ROLLBACK 為結(jié)束的事務(wù)處理時(shí),在程序開(kāi)始運(yùn)行后,第一行數(shù)據(jù)能夠被正確返回,經(jīng)由步驟7, 程序回到步驟3, 讀取游標(biāo)的下一行,此時(shí)常會(huì)發(fā)現(xiàn)游標(biāo)未打開(kāi)的錯(cuò)誤信息。其原因就在于當(dāng)一個(gè)事務(wù)結(jié)束時(shí),不管其是以COMMIT TRANSATION 還是以ROLLBACK TRANSATION 結(jié)束,MS SQL SERVER 都會(huì)自動(dòng)關(guān)閉游標(biāo),所以當(dāng)繼續(xù)從游標(biāo)中讀取數(shù)據(jù)時(shí)就會(huì)造成錯(cuò)誤。
    解決這種錯(cuò)誤的方法就是使用SET 命令將CURSOR_CLOSE_ON_COMMIT 這一參數(shù)設(shè)置為OFF 狀態(tài)。其目的就是讓游標(biāo)在事務(wù)結(jié)束時(shí)仍繼續(xù)保持打開(kāi)狀態(tài),而不會(huì)被關(guān)閉。使用SET 命令的格式為:
SET CURSOR_CLOSE_ON_COMMIT OFF
    釋放游標(biāo)
    在使用游標(biāo)時(shí),各種針對(duì)游標(biāo)的操作或者引用游標(biāo)名,或者引用指向游標(biāo)的游標(biāo)變量。當(dāng)CLOSE 命令關(guān)閉游標(biāo)時(shí),并沒(méi)有釋放游標(biāo)占用的數(shù)據(jù)結(jié)構(gòu)。因此常使用DEALLOCATE 命令。通過(guò)該命令可以刪除掉游標(biāo)與游標(biāo)名或游標(biāo)變量之間的聯(lián)系,并且釋放游標(biāo)占用的所有系統(tǒng)資源。其語(yǔ)法規(guī)則為:
    DEALLOCATE { { [GLOBAL] cursor_name } | @cursor_variable_name}
    當(dāng)使用DEALLOCATE @cursor_variable_name 來(lái)刪除游標(biāo)時(shí),游標(biāo)變量并不會(huì)被釋放,除非超過(guò)使用該游標(biāo)的存儲(chǔ)過(guò)程、觸發(fā)器的范圍(即游標(biāo)的作用域)。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    国产成人午夜av一区二区| 欧美黑人在线精品极品| 国产亚洲欧美日韩精品一区| 国产又粗又长又大的视频| 国产精品偷拍视频一区| 欧美黑人黄色一区二区| 人妻熟女欲求不满一区二区| 欧美一区二区三区喷汁尤物| 日韩精品一区二区一牛| 亚洲熟女诱惑一区二区| 欧美日韩国产综合在线| 国产高清三级视频在线观看| 内射精子视频欧美一区二区| 精品一区二区三区不卡少妇av| 激情亚洲内射一区二区三区| 亚洲黄片在线免费小视频| 日韩亚洲激情在线观看| 亚洲高清中文字幕一区二区三区 | 欧美三级精品在线观看| 亚洲日本韩国一区二区三区| 午夜精品福利视频观看| 少妇一区二区三区精品 | 91天堂素人精品系列全集 | 在线观看日韩欧美综合黄片| 国产专区亚洲专区久久| 少妇被粗大进猛进出处故事| 国产免费自拍黄片免费看| 人妻少妇av中文字幕乱码高清| 亚洲欧美日本国产不卡| 国产成人av在线免播放观看av | 午夜视频成人在线免费| 亚洲中文字幕在线综合视频| 尤物久久91欧美人禽亚洲| 国产美女精品人人做人人爽| 成年人免费看国产视频| 国产综合一区二区三区av| 国产精品九九九一区二区| 国产精品一区二区日韩新区| 日韩国产中文在线视频| 激情五月综五月综合网| 免费在线观看欧美喷水黄片 |