SQL Server數(shù)據(jù)庫游標(biāo)的基本操作指南
1. 聲明游標(biāo)
游標(biāo)主要由結(jié)果集合游標(biāo)位置組成的,結(jié)果集是 SELECT 語句
執(zhí)行后返回的,而游標(biāo)位置是指向返回結(jié)果集中的指針;
使用游標(biāo)前必須對游標(biāo)進(jìn)行聲明;
在 SQL Server 數(shù)據(jù)庫中,使用 DECLARE CURSOR 語句
對游標(biāo)進(jìn)行聲明;
游標(biāo)的聲明要對游標(biāo)的滾動(dòng)行為、游標(biāo)所操作的結(jié)果集進(jìn)行設(shè)置;
游標(biāo)的聲明語法格式如下:
DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ] [ FORWARD_ONLY | SCROLL ] [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ] [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ] [ TYPE_WARNING ] FRO select_seatement [ FRO UPDATE [ OF column_name [,..n] ] ]
- cursor_name:指定要聲明游標(biāo)的名稱;
- LOCAL:指定游標(biāo)的作用域,LOCAL 表示游標(biāo)的作用域局部;
- FORWARD_ONLY:指定游標(biāo)只能從第一個(gè)記錄向下滾動(dòng)到最后一條記錄;
- STATIC:定義一個(gè)游標(biāo)使用數(shù)據(jù)的臨時(shí)副本,對游標(biāo)的所有請求都通過 tempdb 中的臨時(shí)表得到應(yīng)答,提取數(shù)據(jù)時(shí)對該游標(biāo)不能反映基表數(shù)據(jù)修改的結(jié)果;靜態(tài)游標(biāo)不允許更改;
- DYNAMIC:表示當(dāng)游標(biāo)滾動(dòng)時(shí),動(dòng)態(tài)游標(biāo)反映對結(jié)果集內(nèi)所有數(shù)據(jù)的更改;
- KEYSET:指定打開游標(biāo)時(shí),游標(biāo)中記錄順序和成員身份已被固定,對進(jìn)行唯一標(biāo)識的鍵集內(nèi)置在 tempdb 內(nèi)一個(gè)稱為 keyset
- 的表中;
- READ_ONLY|SCROLL_LOCKS|OPTIMISTIC:第一個(gè)參數(shù)表示游標(biāo)為只讀游標(biāo),SCROLL_LOCKS 表示在使游標(biāo)的結(jié)果集時(shí)放置鎖,當(dāng)游標(biāo)對數(shù)據(jù)進(jìn)行讀取時(shí),數(shù)據(jù)庫會(huì)對記錄進(jìn)行鎖定,保證數(shù)據(jù)的一致性;OPTIMISTIC的作用在于通過游標(biāo)讀取數(shù)據(jù),若讀取數(shù)據(jù)之后被更改,那么通過游標(biāo)定位進(jìn)行的更新和刪除操作不成功;
- select_statement:指定游標(biāo)所用結(jié)果集的 SELECT 語句;
注意: 若 GROBAL 和 LOCAL
參數(shù)都未指定,默認(rèn)值就由 default to local cursor 數(shù)據(jù)選項(xiàng)的設(shè)置控制;
例子1:聲明名稱為 cursor_B 的標(biāo)準(zhǔn)游標(biāo),如下所示:
declare cursor_B cursorfor select * from B
上述定義了一個(gè)名為 cursor_B 的游標(biāo),游標(biāo)所操作的結(jié)果集從 SELECT 語句中得到;
例子2:聲明名稱為 cursor_B_read de 的只讀游標(biāo),如下所示:
declare cursor_B_read cursor for select * from B for read only
上述代碼中與標(biāo)準(zhǔn)的定義游標(biāo)過程相比多出了 FOR READ ONLY 語句
,表名該游標(biāo)的記錄只能被讀取,不能進(jìn)行被讀取,不能進(jìn)行更改;
例子3:聲明名稱稱為 curesor_B_update 的更改標(biāo)簽,如下所示:
declare cursor_B_update cursor for select * from B for update
2. 打開游標(biāo)
使用 OPEN 語句
打開 Transa-SQL 服務(wù)器游標(biāo),執(zhí)行 OPEN 語句
的過程,按照 SELECT 語句
填充數(shù)據(jù),當(dāng)打開游標(biāo)時(shí),游標(biāo)的位置在數(shù)據(jù)集的第一行,打開游標(biāo)的語法格式如下:
OPEN [GLOBAL] cursor_name | cursor_variable _name
例子1:打開游標(biāo) cursor_B,如下所示:
open cursor_B
打開游標(biāo)后,可進(jìn)行數(shù)據(jù)操作;
打開全局游標(biāo):
open global cursor_B
打開游標(biāo)是對數(shù)據(jù)庫進(jìn)行一些 SQL SELECT 的操作,將耗費(fèi)一段時(shí)間,取決于使用的系統(tǒng)性能和這條語句的復(fù)雜性;
3. 讀取游標(biāo)中的數(shù)據(jù)
打開游標(biāo)后就能讀取數(shù)據(jù)集中的記錄,用 FETCH 語句
能對數(shù)據(jù)集總的數(shù)據(jù)進(jìn)行某一行讀?。?/p>
FETCH 語法的格式如下:
FETCH [ [ NEXT | PRIOR | FIRST | LAST | ABSOLUTE {n | @nvar} | relative {n | @nvar} ] FROM ] {{ [ GLOBAL ] cursor_name } | @cursor_variable_name } { INTO @variable_name [,...n] }
- NEXT:返回結(jié)果集中當(dāng)前行的下一行記錄,若讀取的是第一行記錄,就返回第一行;NEXT 為默認(rèn)的讀取選項(xiàng);
- PRIOR:返回結(jié)果集中當(dāng)前行的一條記錄,若當(dāng)前行的第一條記錄,就不返回,將游標(biāo)定義到第一條記錄;
- FIRST:返回結(jié)果集中的第一條記錄,并把第一行作為當(dāng)前行;
- LAST:返回結(jié)果集中的最后一條記錄,并把最后一行作為當(dāng)前行;
- ABSOLUTE n:若 n 為正數(shù),就返回從游標(biāo)末尾開始的 n 行,并返回作為新的當(dāng)前行;若 n 為負(fù)值,就返回從游標(biāo) 末尾開始的第 n 行,并返回行為作為新的當(dāng)前行;若 n 為 0,就返回當(dāng)前行;
- RELATIVE n:若 n 為正數(shù),就返回從當(dāng)前行開始的第 n 行;若 n 為負(fù)數(shù),就返回當(dāng)前行之前的第 n 行;若為 0,就返回當(dāng)前行;
- GLOBAL:指定游標(biāo)的作用域?yàn)槿钟螛?biāo);
- cursor_name:指定要打開游標(biāo)的名稱;
- INTO@variable_name[, ... n]:將記錄中提取的字段信息存儲(chǔ)到局部變量中;
例子 1:利用之前創(chuàng)建的游標(biāo) cursor_B_read 檢索 B表中的記錄
declare cursor_B_read cursor for select * from B open cursor_B_read fetch next from cursor_B_read while @@FETCH_STATUS = 0 begin fetch next from cursor_B_read end
在使用游標(biāo)對數(shù)據(jù)進(jìn)行讀取時(shí)可聲明一個(gè)游標(biāo)變量,使用關(guān)鍵字 SET
對游標(biāo)進(jìn)行賦值;
對游標(biāo)賦值的操作步驟:先創(chuàng)建一個(gè)游標(biāo),打開后將值賦予變量,最后通過 FETCH 語句
從變量中讀取值;
例子 2:創(chuàng)建 cursor_S 游標(biāo),并將值賦予 @Mchr 游標(biāo)變量
declare @Mchr cursor declare cursor_S cursor for select * from s; open cursor_S set @Mchr = cursor_S fetch next from @Mchr while @@FETCH_STATUS = 0 begin fetch next from @Mchr end close @Mchr deallocate @Mchr
先聲明了游標(biāo)變量 @Mchr,再創(chuàng)建一個(gè) cursor_S 游標(biāo)打開游標(biāo)后將值賦給 @Mchr,最后用 FEECH 讀取變量中的數(shù)據(jù)內(nèi)容;
FETCH 語法
是游標(biāo)使用的核心,使用游標(biāo)能逐條記錄到查詢結(jié)果;已經(jīng)聲明并打開一個(gè)游標(biāo)后,就能將數(shù)據(jù)放入任意的變量中;
在 FETCH 語句中,讀者能指定游標(biāo)的名稱和目標(biāo)的變量名稱;
注意: 若在 SELECT 語句
中使用了 DISTINCT、UNION、GROUP BY 語句
,且在選擇中包含了聚合表達(dá)式,游標(biāo)就自動(dòng)為 INSENSITIVE
的游標(biāo);
4. 關(guān)閉游標(biāo)
SQL Server 數(shù)據(jù)庫在創(chuàng)建一個(gè)游標(biāo)后,數(shù)據(jù)庫服務(wù)器會(huì)開辟一片存儲(chǔ)空間用于存放游標(biāo)返回的數(shù)據(jù)集;在游標(biāo)使用完后一定要養(yǎng)成關(guān)閉游標(biāo)的習(xí)慣,這樣就能釋放服務(wù)器為游標(biāo)開辟的內(nèi)存空間;
在處理完游標(biāo)中的數(shù)據(jù)之后,用 CLOSE 命令能關(guān)閉一個(gè)已打開的游標(biāo);
語法格式如下:
CLOSE [ CLOBAL ] cursor_name | cursor_variable_naem
例子1:關(guān)閉名稱為 cursor_B 的游標(biāo)
close cursor_B
游標(biāo)可應(yīng)用在存儲(chǔ)過程、觸發(fā)器等中,若在聲明游標(biāo)上與釋放游標(biāo)之間使用了事務(wù)結(jié)構(gòu),在結(jié)束事務(wù)時(shí)游標(biāo)就會(huì)自動(dòng)關(guān)閉;
具體步驟如下:
- 聲明一個(gè)游標(biāo);
- 打開游標(biāo);
- 讀取游標(biāo);
BEGIN TRANSATION
;- 數(shù)據(jù)處理;
COMMIT TRANSATION
;
注意: 打開游標(biāo)后,SQL Server 服務(wù)器會(huì)專門為游標(biāo)開辟一定的內(nèi)存空間用于存放游標(biāo)操作的數(shù)據(jù)結(jié)果集,同時(shí)游標(biāo)的使用也會(huì)根據(jù)具體情況對某些數(shù)據(jù)進(jìn)行封鎖;
所以在不使用游標(biāo)時(shí)一定要關(guān)閉游標(biāo),以通知服務(wù)器釋放游標(biāo)所占用的資源;
關(guān)閉游標(biāo)后,可再次打開游標(biāo),在一個(gè)批處理中,也能多次打開和關(guān)閉游標(biāo);
5. 釋放游標(biāo)
當(dāng)用戶確定某個(gè)游標(biāo)不再使用時(shí),應(yīng)當(dāng)即使使用 DEALLOCATE 命令釋放游標(biāo),SQL Server 將刪除這個(gè)游標(biāo)的數(shù)據(jù)結(jié)構(gòu);
語法如下所示:
DEALLOCATE [GLOBAL]
游標(biāo)被釋放后據(jù)不能再使用 OPEN 命令
再次打開了;
關(guān)閉游標(biāo)和釋放游標(biāo)的區(qū)別在于,關(guān)閉沒有把游標(biāo)運(yùn)行所占用的內(nèi)存空間釋放,若再次打開游標(biāo),還能照常使用,若是釋放,就是將游標(biāo)占用的資源釋放;若再想使用游標(biāo),就必須重新建立;
總結(jié)
到此這篇關(guān)于SQL Server數(shù)據(jù)庫游標(biāo)的基本操作指南的文章就介紹到這了,更多相關(guān)SQLServer游標(biāo)基本操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SQL Server 監(jiān)控磁盤IO錯(cuò)誤,msdb.dbo.suspect_pages
suspect_pages 表位于 msdb 數(shù)據(jù)庫中,是在 SQL Server 2005 中引入的。用于維護(hù)有關(guān)可疑頁的信息的 suspect_pages2014-10-10group by 按某一時(shí)間段分組統(tǒng)計(jì)并查詢(推薦)
這篇文章主要介紹了group by 按某一時(shí)間段分組統(tǒng)計(jì)并查詢,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11SQLServer導(dǎo)出數(shù)據(jù)到MySQL實(shí)例介紹
本文為大家詳細(xì)介紹下從SQLServer導(dǎo)出數(shù)據(jù)并將數(shù)據(jù)導(dǎo)入到MySQL,具體的實(shí)現(xiàn)如下,感興趣的朋友可以參考下哈2013-07-07教你幾種在SQLServer中刪除重復(fù)數(shù)據(jù)方法
數(shù)據(jù)庫的使用過程中由于程序方面的問題有時(shí)候會(huì)碰到重復(fù)數(shù)據(jù),重復(fù)數(shù)據(jù)導(dǎo)致了數(shù)據(jù)庫部分設(shè)置不能正確設(shè)置……2010-04-04