在資料庫開發過程中,當你檢索的資料只是一條記錄時,你所編寫的事務語句**往往使用select insert 語句。但是我們常常會遇到這樣情況,即從某一結果集中逐一地讀取一條記錄。那麼如何解決這種問題呢?游標為我們提供了一種極為優秀的解決方案。
1.1 游標和游標的優點
在資料庫中,游標是乙個十分重要的概念。游標提供了一種對從表中檢索出的資料進行操作的靈活手段,就本質而言,游標實際上是一種能從包括多條資料記錄的結果集中每次提取一條記錄的機制。游標總是與一條t_sql 選擇語句相關聯因為游標由結果集(可以是零條、一條或由相關的選擇語句檢索出的多條記錄)和結果集中指向特定記錄的游標位置組成。當決定對結果集進行處理時,必須宣告乙個指向該結果集的游標。如果曾經用 c 語言寫過對檔案進行處理的程式,那麼游標就像您開啟檔案所得到的檔案控制代碼一樣,只要檔案開啟成功,該檔案控制代碼就可代表該檔案。對於游標而言,其道理是相同的。可見光標能夠實現按與傳統程式讀取平面檔案類似的方式處理來自基礎表的結果集,從而把表中資料以平面檔案的形式呈現給程式。
我們知道關聯式資料庫管理系統實質是面向集合的,在ms sql server 中並沒有一種描述表中單一記錄的表達形式,除非使用where 子句來限制只有一條記錄被選中。因此我們必須借助於游標來進行面向單條記錄的資料處理。
由此可見,游標允許應用程式對查詢語句select 返回的行結果集中每一行進行相同或不同的操作,而不是一次對整個結果集進行同一種操作;它還提供對基於游標位置而對錶中資料進行刪除或更新的能力;而且,正是游標把作為面向集合的資料庫管理系統和面向行的程式設計兩者聯絡起來,使兩個資料處理方式能夠進行溝通。
1.2 游標種類
ms sql server 支援三種型別的游標:transact_sql 游標,api 伺服器游標和客戶游標。
(1) transact_sql 游標
transact_sql 游標是由declare cursor 語法定義、主要用在transact_sql 指令碼、儲存過程和觸發器中。transact_sql 游標主要用在伺服器上,由從客戶端傳送給伺服器的transact_sql 語句或是批處理、儲存過程、觸發器中的transact_sql 進行管理。 transact_sql 游標不支援提取資料塊或多行資料。
(2) api 游標
api 游標支援在ole db, odbc 以及db_library 中使用游標函式,主要用在伺服器上。每一次客戶端應用程式呼叫api 游標函式,ms sql sever 的ole db 提供者、odbc驅動器或db_library 的動態鏈結庫(dll) 都會將這些客戶請求傳送給伺服器以對api游標進行處理。
(3) 客戶游標
客戶游標主要是當在客戶機上快取結果集時才使用。在客戶游標中,有乙個預設的結果集被用來在客戶機上快取整個結果集。客戶游標僅支援靜態游標而非動態游標。由於伺服器游標並不支援所有的transact-sql 語句或批處理,所以客戶游標常常僅被用作伺服器游標的輔助。因為在一般情況下,伺服器游標能支援絕大多數的游標操作。
由於api 游標和transact-sql 游標使用在伺服器端,所以被稱為伺服器游標,也被稱為後台游標,而客戶端游標被稱為前台游標。在本章中我們主要講述伺服器(後台)游標。
select count(id) from info
select * from info
--清除所有記錄
truncate table info
declare @i int
set @i=1
while @i<1000000
begin
insert into info values('justin'+str(@i),'深圳'+str(@i))
set @i=@i+1
end--開啟游標,在游標關閉或刪除前都有效
open my_cursor
--關閉游標
close my_cursor
--宣告區域性變數
declare @id int,@name varchar(20),@address varchar(20)
--定位到指定位置的記錄
fetch absolute 56488 from my_cursor into @id,@name,@address
select @id as id,@name as name,@address as address
--定位到當前記錄相對位置記錄
fetch relative -88 from my_cursor into @id,@name,@address
select @id as id,@name as name,@address as address
--定位到當前記錄前一條
fetch prior from my_cursor into @id,@name,@address
select @id as id,@name as name,@address as address
--定位到當前記錄後一條
fetch next from my_cursor into @id,@name,@address
select @id as id,@name as name,@address as address
--定位到首記錄
fetch first from my_cursor into @id,@name,@address
select @id as id,@name as name,@address as address
--定位到尾記錄
fetch last from my_cursor into @id,@name,@address
select @id as id,@name as name,@address as address
例項:use database1
declare my_cursor cursor scroll dynamic
/**//*scroll表示可隨意移動游標指 針(否則只能向前),dynamic表示可以讀寫游標(否則游標唯讀)*/
forselect productname from product
open my_cursor
declare @pname sysname
fetch next from my_cursor into @pname
while(@@fetch_status=0)
begin
print 'product name: ' + @pname
fetch next from my_cursor into @pname
endfetch first from my_cursor into @pname
print @pname
/**//*update product set productname='zzg' where current of my_cursor */
/**//*delete from product where current of my_cursor */
close my_cursor
deallocate my_cursor
1.4 游標的高階技巧
儘管目前基於sql語句的後台資料庫所支援的語言都大致相當,但對游標的支援卻有著一些差異,例如對滾動游標支援。所謂滾動游標,就是程式設計師可以指定游標向前後任意乙個方向滾動。如在informix中,您甚至還可以將游標滾向結果集開頭或末尾,使用的語句分別是fetch first,fetch last、fetch prior和fetch next。當程式設計師用fetch語句,其預設是指fetch next。由於滾動是在資料庫後台實現的,所以滾動游標為使用者程式設計提供了極大的方便。
對游標支援的另乙個不同是可修改游標。上述游標的使用都是指唯讀游標,而象oracle、sybase等資料庫卻另外支援可作修改的游標。使用這樣的資料庫,您可以修改或刪除當前游標所在的行。例如修改當前游標所在行的使用者的餘額,我們可以如下操作:
update customer
set balance=1000
where current of customercursor;
刪除當前行的操作如下:
delete from customer
where current of customercursor;
但是如果您當前使用的資料庫是sybase,您需要修改資料庫的引數,將游標可修改的值定為1,才能執行上述操作。這一賦值在連線資料庫的前後進行均可。
sqlca.dbparm="cursor update=1"
另外乙個內容是動態游標,也就是說您可以執行過程中動態地形成游標的select語句。這同在powerbuilder中動態地使用嵌入式sql一樣,需要用到dynamicstagin-garea等資料型別,這已超出了本節的範圍。
SQL游標原理和使用方法
在 資料庫開發過程中,當你檢索的資料只是一條記錄時,你所編寫的事務語句 往往使用select insert 語句。但是我們常常會遇到這樣情況,即從某一結果集中逐一地讀取一條記錄。那麼如何解決這種問題呢?游標為我們提供了一種極為優秀的解決方案。1.1 游標和游標的優點 在資料庫中,游標是乙個十分重要的...
SQL游標原理和使用方法
在資料庫開發過程中,當你檢索的資料只是一條記錄時,你所編寫的事務語句 往往使用select insert 語句。但是我們常常會遇到這樣情況,即從某一結果集中逐一地讀取一條記錄。那麼如何解決這種問題呢?游標為我們提供了一種極為優秀的解決方案。1.1 游標和游標的優點 在資料庫中,游標是乙個十分重要的概...
SQL游標原理和使用方法
在資料庫開發過程中,當你檢索的資料只是一條記錄時,你所編寫的事務語句 往往使用select insert 語句。但是我們常常會遇到這樣情況,即從某一結果集中逐一地讀取一條記錄。那麼如何解決這種問題呢?游標為我們提供了一種極為優秀的解決方案。1.1 游標和游標的優點 在資料庫中,游標是乙個十分重要的概...