張潤++方繼才
摘要:針對一些數(shù)據(jù)操作直接使用SQL語句無法處理的問題,在深入分析此類問題遍歷操作的基礎上,文中結合SQL中的游標相關知識和使用規(guī)則,給出了一種基于SQL游標的數(shù)據(jù)處理方法,最后在SQL Server 2012環(huán)境的基礎上,對研究所述進行了相關驗證,驗證結果表明此類方法的有效性。
關鍵詞: SQL Server; 游標; 結果集; 遍歷
中圖分類號: TP391
文獻標志碼: A
文章編號:2095-2163(2016)06-0084-04
0引言
SQL Server 2012是一款功能完善、且設計高端的關系型數(shù)據(jù)庫管理系統(tǒng),關系型數(shù)據(jù)庫中的數(shù)據(jù)操作通常都是面向整個結果集的,而結果集又是由Select、Update、Insert等語句返回的所有滿足Where子句條件的行。在數(shù)據(jù)庫的開發(fā)過程中,常常使用T-SQL語句將整個結果集作為一個單元來進行處理,然而實際上很多時候用戶需要對結果集中的某一行或者多行分設相同或不同的操作,例如要從結果集中逐一讀取每一條記錄、更新或者刪除結果集對應表中某一行的數(shù)據(jù)等等,此時若僅是運用T-SQL語句則將無法滿足這一功能需求,為此就需要借助于游標機制來實現(xiàn)逐條記錄的數(shù)據(jù)處理\[1\]。而且,還有很多應用程序,尤其是將SQL 嵌入到其它開發(fā)語言時,這些語言或程序并不能把整個結果集作為一個單元來開展有效的控制處理,而只能處理一行或者部分行,這時候就更加需要使用游標。
[BT4]1SQL游標的概述
游標作為數(shù)據(jù)庫的重要對象,不僅表現(xiàn)為一種數(shù)據(jù)訪問機制,同時也是一種數(shù)據(jù)處理方法,具有對結果集進行逐行處理的能力;而且,游標還提供了一種對從表中檢索出的數(shù)據(jù)定制各類操作的靈活手段。就本質而言,游標實際上即是一種能從包括多條數(shù)據(jù)記錄的結果集中每次提取一條記錄的機制\[2\]。游標就好比C語言中的指針,通過與某個查詢結果構建技術聯(lián)系,可以指定結果集中的任何位置,然后允許用戶對指定位置的數(shù)據(jù)進行處理,以達到用戶處理數(shù)據(jù)的復雜目的需求,如:在結果集中一次一行或者多行向前或向后瀏覽數(shù)據(jù)的操作。
在游標的實現(xiàn)上,則總是與一條T-SQL語句相關聯(lián)。這是因為游標是由結果集和結果集中指向特定記錄的游標位置集結聯(lián)合所組成,組成示意如圖1所示。其中,游標結果集是定義游標的SQL語句返回的行的集合,游標位置則是指向這個行集合中某一行的當前指針。在SQL Server中,用戶可以通過SQL語句逐一地從游標中讀取記錄,還可以使用游標處理結果集中的數(shù)據(jù),具體包括了更新、刪除等操作。
2SQL游標的作用及優(yōu)勢
在SQL Server中,游標主要是用來對結果集引入“行集”性質的相關操作。也就是說,當在存儲過程、觸發(fā)器和批處理中使用T-SQL語句返回結果集的多條記錄時,游標則給出了一個可以對記錄進行逐條處理的有效方法。
研究可得,使用游標的重點效應優(yōu)勢可作如下闡析:
1)游標允許用戶訪問或處理一個集合里的單獨數(shù)據(jù)行,而不受其他行的限制約束,這也是游標設計上的鮮明優(yōu)勢?;诖?,用戶就可以使用這些數(shù)據(jù)生成SQL代碼并立即執(zhí)行或輸出,這樣就能降低系統(tǒng)開銷和潛在的阻隔情況。
2)使用游標查看或處理數(shù)據(jù)使得用戶的操作過程更加靈活、高效、方便。
3)在SQL Server數(shù)據(jù)庫系統(tǒng)中,游標可分為服務器游標和客戶游標。相對于客戶游標而言,服務器游標可以大大減少網(wǎng)絡數(shù)據(jù)傳輸?shù)拈_銷,從而提高應用程序訪問數(shù)據(jù)庫的速度和效率。
4)作為面向集合的數(shù)據(jù)庫管理系統(tǒng)(RDBMS)和面向行的程序設計之間的設計媒介,游標可使得這2種處理方式能夠獲得有效拓展連接\[3\]。
[BT4]3SQL游標的使用
SQL游標一般用于存儲過程、觸發(fā)器和Transact-SQL腳本中。在SQL Server中使用游標處理數(shù)據(jù)時需要遵循一定的規(guī)則,研究給出其使用流程如圖2所示。
從圖 2 中可以看出,SQL游標的使用流程可具體表述如下:首先聲明游標,然后打開游標,再從游標中提取數(shù)據(jù)應用于相關操作,直至所有記錄均已標明處理,由此即關閉并釋放游標。
[BT5]3.1游標的聲明
與變量一樣,在游標使用前也要預先設定游標聲明。通過聲明來定義游標的名稱、游標指向的結果集和游標的屬性。簡單的示例語句為:
Declare cur_xsxx Cursor For Select xh,xm,xb,sfz From xsxx;
該語句定義了一個名為cur_xsxx 的游標,且指向一個從xsxx(學生信息表)表中查詢出xh、xm、xb和sfz字段內(nèi)容的結果集。
在上述示例語句中,游標名稱Cursor_name(游標變量@Cursor_name)是用戶此后若涉及到該游標時將會使用的名字,關鍵字Cursor指明此變量是游標類型,關鍵字For和Select語句定義了游標的內(nèi)容。此外,聲明游標的T-SQL語句還提供了一些更多的關鍵字選項,如Scroll、Static、Read_Only等等,各個選項也將呈現(xiàn)各不相同的作用。
[BT5]3.2游標的打開
游標在發(fā)出聲明后,必須使用Open語句來打開游標,才能展開進一步的數(shù)據(jù)提取。打開游標的示例語句為:
Open cur_xsxx。
打開游標時,需要注意兩點:
1)若打開的是全局游標,則必須添加關鍵字Global,否則打開的就將是默認的局部游標。
2)游標的打開可能會產(chǎn)生問題,SQL Server即是通過@@Error全局變量的值來判斷游標打開的成功與否:為0表示成功,為1表示失敗。
[BT5]3.3游標的提取
打開游標后,就可以讀取游標中的數(shù)據(jù)了。提取游標的示例語句為:
Fetch Next From cur_xsxx into @xh,@xm。
該語句表示將游標結果集所指的記錄中字段xh和xm的值賦給局部變量@xh和@xm中。在讀取游標時,數(shù)據(jù)所在的記錄位置總共設有6個關鍵字(Next、Prior、First、Last、Absolute和Relative)用于條件選擇。
[BT5]3.4游標的關閉和釋放
在游標使用進程結束后,要及時關閉和釋放游標,以利于服務器釋放曾分配給游標占用的SQL Server系統(tǒng)資源。關閉游標的示例語句為:
Close cur_xsxx;
釋放游標的示例語句為:
Deallocate cur_xsxx。
游標被釋放后就不能重新打開了,除非再次重新聲明游標。
[BT4]4SQL游標的應用實例與分析
游標的應用重點可表現(xiàn)在2個方面:
1)使用游標從結果集中檢索數(shù)據(jù),以實現(xiàn)對數(shù)據(jù)的逐行查看,也就是平時經(jīng)常遇到的一種操作——遍歷。
2)使用游標可以對結果集中的數(shù)據(jù)進行更新或刪除\[4\]。改變游標中的數(shù)據(jù),自然會影響到數(shù)據(jù)庫中基礎表的數(shù)據(jù),若要使游標中的數(shù)據(jù)不致發(fā)生修改,則可以在聲明游標時添加Insensitive選項。
在此,將以某個學校學費收繳管理系統(tǒng)中的學校收費數(shù)據(jù)庫為背景,研究給出2個具體實例來闡釋說明SQL Server中游標的使用方法和應用實現(xiàn)。
[BT5]4.1游標的遍歷
4.1.1應用說明
所謂遍歷,就是指沿著某條搜索路線,依次對樹中的每個結點均將經(jīng)歷一次的訪問。而對于游標的遍歷而言,游標所對應的結果集是指樹,結果集中的每一條記錄(每一行)是指每個結點,游標的遍歷實際上就是指游標的逐行取數(shù)操作。
在SQL Server中,游標的使用主要集中在對游標所指結果集的遍歷操作。通常在執(zhí)行Fetch語句(讀取游標數(shù)據(jù))的時候,可以借助于全局變量@@Fetch_Status(返回游標當前的狀態(tài))的值來判斷提取數(shù)據(jù)的操作是否成功。若值為0,表明讀取數(shù)據(jù)成功;若值為-1,表明執(zhí)行失敗或此行不在結果集中;若值為-2,表明讀取的數(shù)據(jù)行不存在。在實際研發(fā)中,F(xiàn)etch語句經(jīng)常和While語句結合使用來生成對結果集中的每一行數(shù)據(jù)實現(xiàn)遍歷的操作。下面則通過一個完整實例來直觀展現(xiàn)游標便利的功能應用流程。
4.1.2實例分析
[HT5”H][ST5”HZ]實例一[HT5”SS][ST5”BZ]利用游標遍歷從xxsf數(shù)據(jù)庫的xsxx(學生信息表)和zysf(專業(yè)收費表)中顯示所有文學院學生的專業(yè)代碼(zydm)、專業(yè)名稱(zymc)、隸屬院系(lsyx)、學號(xh)和姓名(xm),并以報表的形式提供結果輸出。
當前數(shù)據(jù)庫的基礎表xsxx和zysf,表的結構可如表1和表2,字段zydm、zymc和lsyx來源于表2,字段zydm、xh和xm來源于表1。2張表將通過公共字段zydm建立連接。
4.2使用游標更新數(shù)據(jù)
4.2.1應用說明
游標在聲明的時候若定義為可更新的,則可用Update語句來修改基礎表中某行的數(shù)據(jù),當然也可以執(zhí)行刪除某行的操作,但不能插入新行。
一般情況下,在Where子句中給定了條件才能修改或刪除數(shù)據(jù),但鑒于游標不能自動對行實現(xiàn)更新或刪除的原因,因此在聲明游標的時候使用了For Update Of語句,這樣就可以在Update或Delete命令中利用Where Current Of關鍵字直接修改或刪除當前游標中存儲的數(shù)據(jù),而不必使用Where子句重新給出指定條件\[5\]。
4.2.2實例分析
[HT5”H][ST5”HZ]實例二[HT5”SS][ST5”BZ]利用游標將數(shù)據(jù)表xsxx中第3位同學的入學年份(rxnf)改為2012年(這里只顯示xsxx表中的rxnf、xh、xm、xb和sfz字段)。
關鍵代碼如下:
DECLARE cur_xg SCROLL CURSOR FOR
SELECT rxnf,xh,xm,xb,sfz from xsxx
FOR UPDATE OF rxnf --定義表中需要修改的數(shù)據(jù)列
OPEN cur_xg
FETCH ABSOLUTE 3 FROM cur_xg--返回第3行并將其變?yōu)楫斍靶?/p>
UPDATE xsxx SET rxnf=2012--更新當前行的列值
WHERE CURRENT OF cur_xg--當前游標指針所指的當前行數(shù)據(jù)
CLOSE cur_xg
DEALLOCATE cur_xg
這里需要注意的是,游標的第二種應用是一種不規(guī)范的更新數(shù)據(jù)的途徑,很容易造成數(shù)據(jù)的不一致,因此通常狀況下并不選用游標來設計更新數(shù)據(jù)表中的數(shù)據(jù)。
另外,還需提及的就是,本文實例所用的數(shù)據(jù)表均基于xxsf(學校收費數(shù)據(jù)庫)中的2個表,分別是:
xsxx(rxnf,xh,xm,xb,ksh,sfz,zydm,zsid)
zysf(zydm,zymc,lsyx,pycc,xxnx,xfbz,jcfbz)
[BT4]5結束語
SQL Server中的游標在原理上具有C語言指針一樣的語言結構,相應地則設計提供了一種在服務器內(nèi)部處理結果集的方法。使用游標可以通過遍歷操作逐一地從結果集中實現(xiàn)數(shù)據(jù)讀取,也可以對結果集中某些數(shù)據(jù)重點加設更新或刪除的操作。本文以學校收費數(shù)據(jù)庫為背景并結合具體的實例來闡述游標的使用,游標可以面向結果集中的每一行進行相同或不同的操作,這不僅提升了SQL語句處理復雜查詢的能力,而且還降低了系統(tǒng)開銷和潛在的阻隔情況,在一定程度上解決了許多應用程序不能把整個結果集作為一個單元來處理的問題。
參考文獻:
趙慧玲,毛應爽,孟憲穎. 基于SQL游標的研究與應用[J]. 科技創(chuàng)新導報,2012(28):31-32.
[2] 劉志成,寧云智,劉釗,編著. SQL Server實例教程[M]. 北京:電子工業(yè)出版社,2013.
[3] 薛麗香,汪東芳. 淺談SQL Server數(shù)據(jù)庫中游標的使用[J]. 福建電腦,2016(6):157-158.
[4] 陳芳勤. SQL Server 2000中游標的應用[J]. 中國科技信息,2008(13):96,99.
[5] 黃龍軍. 游標在Online Judge中的應用[J]. 紹興文理學院學報(自然科學),2012,32(8):26-29.