SQL SERVER 参考:游标(Cursor)的讲解与实例
當決定對結果集進行處理時,必須聲明一個指向該結果集的游標。如果曾經用 C 語言寫過對文件進行處理的程序,那么游標就像您打開文件所得到的文件句柄一樣,只要文件打開成功,該文件句柄就可代表該文件。對于游標而言,其道理是相同的。可見游標能夠實現按與傳統程序讀取平面文件類似的方式處理來自基礎表的結果集,從而把表中數據以平面文件的形式呈現給程序。
我們知道關系數據庫管理系統實質是面向集合的,在MS SQL SERVER 中并沒有一種描述表中單一記錄的表達形式,除非使用where 子句來限制只有一條記錄被選中。因此我們必須借助于游標來進行面向單條記錄的數據處理。
????
由此可見,游標允許應用程序對查詢語句select 返回的行結果集中每一行進行相同或不同的操作,而不是一次對整個結果集進行同一種操作;它還提供對基于游標位置而對表中數據進行刪除或更新的能力;而且,正是游標把作為面向集合的數據庫管理系統和面向行的程序設計兩者聯系起來,使兩個數據處理方式能夠進行溝通。
每一個游標必須有四個組成部分這四個關鍵部分必須符合下面的順序;
1.DECLARE 游標
2.OPEN 游標
3.從一個游標中FETCH 信息
4.CLOSE 或DEALLOCATE 游標
通常我們使用DECLARE 來聲明一個游標聲明一個游標主要包括以下主要內容:
游標名字
數據來源(表和列)
選取條件
屬性(僅讀或可修改)
其語法格式如下:
FOR select_statement
[FOR {READ ONLY | UPDATE [OF column_name [,...n]]}]
其中:
cursor_name 指游標的名字。
INSENSITIVE
表明MS SQL SERVER 會將游標定義所選取出來的數據記錄存放在一臨時表內(建立在tempdb 數據庫下)。對該游標的讀取操作皆由臨時表來應答。因此,對基本表的修改并不影響游標提取的數據,即游標不會隨著基本表內容的改變而改變,同時也無法通過游標來更新基本表。如果不使用該保留字,那么對基本表的更新、刪除都會反映到游標中。
游標指針示意圖
詳細:
1.定義一個標準游標:
declare mycursor cursor for select * from yuangong2.定義一個只讀游標:
declare mycursor cursor for select * from yuangong for read only3.定義一個可寫游標:
declare mycursor1 cursor for select * from yuangong for update of姓名,性別,年齡,基本工資,獎金,所得稅,應發工資
注: scroll 只能對只讀游標起作用
4.打開游標:open 游標名
如:
declare mycursor cursor for select * from yuangongopen mycursor
5.從游標中取數據:fetch,默認情況下,指針指向第一條記錄之前
移動記錄指針的方法:
NEXT?? 下移一條記錄
prior 上移一條記錄
first 第一條記錄
LAST?? 最后一條記錄
absolute n 絕對記錄 第N條記錄
取數據語法:
fetch next|prior|first|last|absolute n????from 游標名 [into 變量名列表]6.關閉游標: close 游標名
暫時關閉游標,還可再使用OPEN打開.
7.釋放游標: deallocate 游標名
從內存中清除游標.如果還想使用,必須再次聲明.
對當前游標狀態進行判斷:
8. @@fetch_status 如果返回是0,說明當前操作是成功的.否則是失敗的.
0 FETCH 語句成功。
-1 FETCH 語句失敗或此行不在結果集中。
-2 被提取的行不存在。
舉例1:
利用游標從學生表中逐條讀取所有數據:
declare @i INTDECLARE @TN CHAR(8),@FU CHAR(20)
declare mycursor cursor for select sno,sname from student
open mycursor
select @i=count(*) from student
while @@fetch_status=0 and @i>1
BEGIN
????fetch next from mycursor INTO @TN,@FU
????set @i=@i-1
PRINT @TN + ' ' + @FU
END
close mycursor
deallocate mycursor
結果:
s1001??? Jack Dong??????????
s1002??? Lucy Dong??????????
s1003??? Brezse Dong????????
s1004??? Andy Liu???????????
s1005??? Jack Chen??
舉例2:
通過游標對讀取的數據進行操作,并輸出不同的結果:
declare @s_name varchar(20),@c_name VARCHAR(64),@sc_core intdeclare my_cur cursor for select sname,cname,scgrade
from student s, course c, studentCourse sc WHERE s.sno=sc.sno AND c.cno=sc.cno
open my_cur
print space(27)+'2007年計算機專業考試系統'
fetch next from my_cur into @s_name,@c_name,@sc_core
while @@fetch_status=0
begin
????if @sc_core<60
????begin
????????print space(20)+@s_name+ @c_name +':不及格 '
????end
????else
????begin
?????????? if @sc_core >=60 and @sc_core <70
?????????? begin
?????????????? print space(20)+@s_name??+ @c_name +':及格 '
?????????? end
?????????? else
?????????? begin
?????????????? if @sc_core>=70 and @sc_core<80
?????????????? begin
??????????????????print space(20)+@s_name + @c_name +':良好'
?????????????? end
?????????????? else
?????????????? begin
??????????????????print space(20)+@s_name + @c_name +':優秀'
?????????????? end
?????????? end
????end
fetch next from my_cur into @s_name,@c_name,@sc_core
end
close my_cur
deallocate my_cur
結果:
???????????????????????????? 2007年計算機專業考試系統
??????????????????? Jack Dong?????????????????????????????? C++ 程序設計:及格
??????????????????? Jack Dong?????????????????????????????? 操作系統:良好
??????????????????? Lucy Dong?????????????????????????????? C++ 程序設計:優秀
??????????????????? Lucy Dong?????????????????????????????? 計算機組成原理:良好
??????????????????? Brezse Dong???????????????????????????? C++ 程序設計:優秀
??????????????????? Brezse Dong???????????????????????????? 面向對象的程序設計方法:不及格
??????????????????? Andy Liu??????????????????????????????? 操作系統:不及格
??????????????????? Andy Liu??????????????????????????????? 計算機組成原理:優秀
使用游標時應注意的問題:
(1) 盡管使用游標比較靈活,可以實現對數據集中單行數據的直接操作,但游標會在下面幾個方面影響系統的性能:
-使用游標會導致頁鎖與表鎖的增加
-導致網絡通信量的增加
-增加了服務器處理相應指令的額外開銷
(2) 使用游標時的優化問題:
-明確指出游標的用途:for read only或for update
-在for update后指定被修改的列
總結
以上是生活随笔為你收集整理的SQL SERVER 参考:游标(Cursor)的讲解与实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Altiris™ IT Manageme
- 下一篇: 梦到掉光了牙齿是什么预兆