1. 程式人生 > 實用技巧 >SQL程式設計之遊標

SQL程式設計之遊標

遊標(Cursor)是類似於C語言指標一樣的結構,在MySQL中它是一種資料訪問機制,允許使用者訪問單獨的資料行,而不是對整個行集進行操作。

在MySQL中,遊標主要包含遊標結果集和遊標位置兩部分,遊標結果集是由定義遊標的 SELECT 語句返回行的集合,遊標位置則是這個結果集中的某一行的指標。

在使用遊標之前首先要宣告遊標,定義 SQL 伺服器遊標的屬性,例如遊標的滾動行為和用於生成遊標所操作的結果集的查詢。

宣告遊標:

select cursor_name cursor for select_statement;

例:為teacher表建立一個名為t_cursor的普通遊標

declare t_cursor cursor for select tno,tname from teacher;

在聲明瞭遊標之後,就可以對遊標進行操作。主要包括開啟遊標、檢索遊標、關閉遊標和釋放遊標。

一、開啟遊標

使用遊標之前必須首先開啟遊標,開啟遊標的語法如下所示。

open cuesor_name;

二、檢索遊標

在開啟遊標之後,就可以開啟遊標提取資料。FETCH 語句的功能是獲取遊標當前指標的記錄,並傳給指定變數列表,注意變數數必須與MySQL遊標返回的欄位數一致。要獲取更多行資料,需要使用迴圈語句去執行 FETCH,其語法如下。

FETCH cursor_name INTO var1[,var2,...];

其中,var1[,var2,...]就是變數列表,這些變數必須在宣告之前定義好。前面曾經提過,遊標是帶一個指標的記錄集,其中指標指向記錄中的某一條特定記錄。從 FETCH 語句的上述定義中不難看出,FETCH 用來移動這個記錄指標。

MySQL的指標是向前只讀的也就是說,只能順序地從開始往後讀取結果集,不能從後往前,也不能直接跳到中間的記錄。

首先,FETCH 離不開迴圈語句。一般使用 Loop 和 while 比較清楚,而且程式碼簡單。這裡使用 Loop 為例,程式碼如下。

fetchloop:Loop
    FETCH T_Cursor INTO v_tno, v_tname;
end Loop;

上述迴圈是死迴圈,沒有退出條件。與 SQL 和 Oracle 不同,MySQL是通過一個 Errorhandler 的宣告來進行判斷的。

declare continue handler for not found ...; 

在MySQL中,當遊標遍歷溢位時,會出現一個預定義的 NOT FOUND 的錯誤(SQLSTATE '02000'),讀者處理這個錯誤時定義一個繼續執行的錯誤處理程式即可。在定義處理程式時定義一個標誌,在迴圈語句裡以這個標誌為結束迴圈的判斷條件就可以了。

create procedure procursor()
begin
declare done int default 0;
declare v_tno varchar(4) default "";
declare v_tname varchar(8) default "";
declare T_cursor cursor for select TNO, Tname from teacher;  --定義遊標
declare continue handler for NOT FOUND done = 1;  -- 定義處理程式
set done = 0;
open T_cursor;  -- 開啟遊標
fetch_Loop:LOOP
fetch T_cursor into v_tno, v_tname;  -- 檢索遊標
if done=1 then
    leave fetch_Loop;
else
    select v_tno,v_tname;
end if;
end loop fetch_Loop;
end

上述語句中的變數 done 儲存的就是 FETCH 操作的結束資訊。如果其值為零,則表示有記錄檢索成功;否則,則 FETCH 語句由於某種原因而操作失敗。

三、關閉遊標

開啟遊標以後,MySQL 伺服器會專門為遊標開闢一定的記憶體空間,以存放遊標操作的資料結果集,同時遊標的使用也會根據具體情況對某些資料進行封鎖。所以在不使用遊標的時候,一定要關閉遊標,以通知伺服器釋放遊標所佔用的資源。

在一個遊標關閉後,如果沒有重新開啟,則不能使用它。但是,使用宣告過的遊標不需要再次宣告。如果不明確關閉遊標,MySQL將會在達到END 語句時自動關閉它。

關閉遊標的具體語法如下所示。

CLOSE cursor_name;

在檢索遊標 T_cursor 後可用如下語法關閉它。

close T_cursor;

經過上面的操作,完成了對遊標 T_cursor 的宣告、開啟、檢索和關閉操作。結束!