1. 程式人生 > >MySQL——遊標

MySQL——遊標

遊標

遊標是一個儲存在MySQL伺服器上的資料庫查詢,它不是一條SELECT語句,而是被該語句檢索出來的結果集。在儲存了遊標之後沒應用程式可以根據需要滾動或瀏覽其中的資料。

注意:

1、和其他DBMS相比,MySQL遊標只能用於儲存過程、函式、迴圈處理。

2、遊標只能一行一行操作,在資料量大的情況下,是不適用的,速度過慢,同時會造成記憶體不足的現象,給伺服器帶來嚴重的效能問題。而且資料庫大部分是面對集合的,業務會比較複雜,而遊標使用會有死鎖,影響其他的業務操作,這樣非常不可取。 

遊標使用規則

1、在使用遊標前必須宣告(定義)它。這個過程實際上沒有檢索資料,它只是定義要使用的SELECT語句。

2、 一旦聲明後必須開啟遊標以供使用。這個過程用前面定義的SELECT語句把資料實際檢索出來。

3、對於填有資料的遊標,根據需要取出(檢索)各行。

4、在結束遊標使用時,必須關閉遊標。

建立遊標

遊標用 DECLARE語句建立,DECLARE命名遊標,並的定義相應的SELECT語句,根據需要帶WHERE和其他子句。

語法

CREATE PROCEDURE 儲存過程名稱()
BEGIN
    DECLARE 遊標名稱 CURSOR
    FOR
    SELECT語句;
END;

開啟、使用、關閉遊標

遊標用OPEN CURSOR語句開啟,語法

OPEN 遊標名稱;

在有個遊標被開啟後,可以使用FETCH語句分別訪問它的每一行。FETCH指定檢索出什麼資料(所需的列),檢索出來的資料儲存在什麼地方,並且還可以向前移動尤標忠的內部行指標,是下一條FETCH語句檢索下一行(不重複讀取同一行)。語法

FETCH [NEXT | PRIOR | FIRST | LAST] FROM <遊標名> [ INTO 變數名1,變數名2,變數名3,…];


NEXT:取下一行的資料,遊標一開始預設的第一行之前,故要讓遊標指向第一行,就必須第一次就執行FETCH NEXT操作

INTO:將一行中每個對應的列下的資料放到與列 的資料型別相同的變數中。

遊標處理完成後應當使用CLOSE CURSOR語句關閉遊標,語法

CLOSE 遊標名稱;

釋放遊標將會釋放所有內部記憶體和資源,因此在每個遊標不再需要時都應該關閉。在一個遊標關閉後,如果沒有重新開啟,則不能使用它,但使用宣告過的遊標不需要再次宣告,只需要用OPEN語句開啟它即可。

注意:(隱含關閉)若不明確的關閉遊標,MySQL將會在到達END語句時自動關閉遊標,不過建議最好是自己明確指明關閉遊標。

例子:

1、從遊標中檢索單個行(對檢索的資料不做任何處理)。

CREATE PROCEDURE p_test()
BEGIN
	/*--定義區域性變數id_num的預設值為4--*/
	DECLARE id_population int;
	
	/*--定義遊標city_cursor--*/
	DECLARE city_cursor CURSOR
	FOR
		SELECT Population
		FROM city;
		
	/*--開啟遊標--*/
	OPEN city_cursor;
	
	/*--檢索資料--*/
	FETCH city_cursor INTO id_population;
	
	/*--關閉遊標--*/
	CLOSE city_cursor;

END;


/*--呼叫儲存過程--*/
CALL p_test();

2、迴圈檢索資料,從第一行到最後一行

CREATE PROCEDURE p_test()
BEGIN
 DECLARE  no_more_record INT DEFAULT 0;
 DECLARE  pID BIGINT(20);
 DECLARE  pValue DECIMAL(15,5);
 DECLARE  cur_record CURSOR
 FOR
	SELECT colA, colB 
	from tableABC;  /*首先這裡對遊標進行定義*/
	
 DECLARE  CONTINUE HANDLER FOR NOT FOUND  SET  no_more_record = 1; /*這個是個條件處理,針對NOT FOUND的條件,當沒有記錄時賦值為1*/
 
 OPEN  cur_record; /*接著使用OPEN開啟遊標*/
 
 FETCH  cur_record INTO pID, pValue; /*把第一行資料寫入變數中,遊標也隨之指向了記錄的第一行*/
 
 WHILE no_more_record != 1 DO
 INSERT  INTO testTable(ID, Value) VALUES  (pID, pValue);
 FETCH  cur_record INTO pID, pValue;
 END WHILE;
 
 CLOSE  cur_record;  /*用完後記得用CLOSE把資源釋放掉*/
 
END


/*--呼叫儲存過程--*/
CALL p_test();