SQL 游標原理和使用方法

2021-05-22 14:00:28 字數 3867 閱讀 9916

資料庫開發過程中,當你檢索的資料只是一條記錄時,你所編寫的事務語句**往往使用select insert 語句。但是我們常常會遇到這樣情況,即從某一結果集中逐一地讀取一條記錄。那麼如何解決這種問題呢?游標為我們提供了一種極為優秀的解決方案。

1.1 游標和游標的優點

在資料庫中,游標是乙個十分重要的概念。游標提供了一種對從表中檢索出的資料進行操作的靈活手段,就本質而言,游標實際上是一種能從包括多條資料記錄的結果集中每次提取一條記錄的機制。游標總是與一條t_sql 選擇語句相關聯因為游標由結果集(可以是零條、一條或由相關的選擇語句檢索出的多條記錄)和結果集中指向特定記錄的游標位置組成。當決定對結果集進行處理時,必須宣告乙個指向該結果集的游標。

我們知道關聯式資料庫管理系統實質是面向集合的,在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 游標使用在伺服器端,所以被稱為伺服器游標,也被稱為後台游標,而客戶端游標被稱為前台游標。在本章中我們主要講述伺服器(後台)游標。

游標操作

使用游標有四種基本的步驟:宣告游標、開啟游標、提取資料、關閉游標。

宣告游標

象使用其它型別的變數一樣,使用乙個游標之前,首先應當宣告它。游標的宣告包括兩個部分:游標的名稱;這個游標所用到的sql語句。如要宣告乙個叫作cus-tomercursor的游標用以查詢位址在北京的客戶的姓名、帳號及其餘額,您可以編寫如下**:

declare customercursor cursor for

select acct_no,name,balance

from customer

where province="北京";

在游標的宣告中有一點值得注意的是,如同其它變數的宣告一樣,宣告游標的這一段**行是不執行的,您不能將debug時的斷點設在這一**行上,也不能用if...end if語句來宣告兩個同名的游標,如下列的**就是錯誤的。

if is_prov="北京"then

declare customercursor cursor for

select acct_no,name,balance

from customer

where province="北京";

else

declare customercursor cursor for

select acct_no,name,balance

from customer

where province〈〉"北京";

end if

--開啟游標,在游標關閉或刪除前都有效

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表示可以讀寫游標(否則游標唯讀)*/

for

select 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

end

fetch 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

SQL游標原理和使用方法

在 資料庫開發過程中,當你檢索的資料只是一條記錄時,你所編寫的事務語句 往往使用select insert 語句。但是我們常常會遇到這樣情況,即從某一結果集中逐一地讀取一條記錄。那麼如何解決這種問題呢?游標為我們提供了一種極為優秀的解決方案。1.1 游標和游標的優點 在資料庫中,游標是乙個十分重要的...

SQL游標原理和使用方法

在資料庫開發過程中,當你檢索的資料只是一條記錄時,你所編寫的事務語句 往往使用select insert 語句。但是我們常常會遇到這樣情況,即從某一結果集中逐一地讀取一條記錄。那麼如何解決這種問題呢?游標為我們提供了一種極為優秀的解決方案。1.1 游標和游標的優點 在資料庫中,游標是乙個十分重要的概...

SQL游標原理和使用方法

在資料庫開發過程中,當你檢索的資料只是一條記錄時,你所編寫的事務語句 往往使用select insert 語句。但是我們常常會遇到這樣情況,即從某一結果集中逐一地讀取一條記錄。那麼如何解決這種問題呢?游標為我們提供了一種極為優秀的解決方案。1.1 游標和游標的優點 在資料庫中,游標是乙個十分重要的概...