MySQL遊標概念與用法詳解
本文例項講述了MySQL遊標概念與用法。分享給大家供大家參考,具體如下:
1、遊標的概念(Cursor)
一條sql,對應N條資源,取出資源的介面,就是遊標,沿著遊標,可以一次取出1行。如果開發過安卓的同學應該知道有一個Api是Cursor,也是讀取SQLite資料庫用的,和這個有點類似。
2、使用遊標的步驟
(1)宣告
使用declare進行宣告
declare 遊標名 cursor for select_statement
(2)開啟遊標
使用open進行開啟
open 遊標名
(3)從遊標中取值
使用fetch進行取值
fetch 遊標名 into var1,var2[,...] --將取到的一行賦值給多個變數
(4)關閉遊標
使用close關閉遊標
close 遊標名
3、建立一個簡單的遊標
需求:從商品表中讀取第一行資料
商品表(goods)資料:
注意:我這裡已經將MySQL的結束識別符號改為 $,如果要知道怎麼設定為$,請參考前面一篇文章:MySQL觸發器。
定義:
create procedure p12() begin /*定義三個變數用於存放商品id,商品名稱,商品庫存量*/ declare row_gid int ; declare row_name varchar(20); declare row_num int; declare getgoods cursor for select gid,name,num from goods; --定義遊標 open getgoods; --開啟遊標 fetch getgoods into row_gid,row_name,row_num;--從遊標中取值 select row_name,row_num; --顯示操作 close getgoods; --關閉遊標 end$
輸出結果:
4、多次取值操作
create procedure p13() begin declare row_gid int ; declare row_name varchar(20); declare row_num int; declare getgoods cursor for select gid,num from goods; open getgoods; fetch getgoods into row_gid,row_num; select row_name,row_num; fetch getgoods into row_gid,row_num; close getgoods; end$
輸出:
注意:當遊標讀到末尾,如果繼續進行取值操作會發生報錯
5、遊標迴圈表中的所有資料
(1)使用計數器來迴圈
create procedure p14() begin declare cnt int default 0; declare i int default 0; declare row_gid int ; declare row_name varchar(20); declare row_num int; declare getgoods cursor for select gid,num from goods; select count(*) into cnt from goods; open getgoods; repeat fetch getgoods into row_gid,row_num; set i:= i+1; until i >= cnt end repeat; close getgoods; end$
輸出結果:
(2)使用越界標誌來控制迴圈
在mysql cursor中,可以宣告declare continue handler
來操作1個越界標誌
語法:
declare continue handler for NOT FOUND statement;
使用:
create procedure p15() begin declare row_gid int ; declare row_name varchar(20); declare row_num int; declare have int default 1; declare getgoods cursor for select gid,num from goods; declare continue handler for NOT FOUND set have:= 0; open getgoods; repeat fetch getgoods into row_gid,row_num; until have = 0 end repeat; close getgoods; end$
輸出結果:
注意:這裡發生了錯誤,這裡輸出了4行資料,而表中只有3行資料,而且還爆出了警告,後面會說怎麼結果這個問題。
程式執行邏輯:
循環遊標->fetch第三條資料->顯示->fetch第四條資料->沒有資料->設定have=0操作->執行continue Handler->程式不退出,執行顯示操作->還是顯示第三條資料
6、continue和exit的區別
continue:若沒有資料返回,程式繼續,並將變數IS_FOUND設為0,這種情況是出現在select XX into XXX from tablename的時候發生的。
exit:若沒有資料返回,退出程式,並將變數IS_FOUND設為0,這種情況是出現在select XX into XXX from tablename的時候發生的。
使用exit來替換continue:
使用exit就不會出現上面的那種情況了,程式執行邏輯:
循環遊標->fetch到第三條資料->顯示->第四次fetch操作->沒有資料->設定 have=0操作->程式直接退出exit
所以就沒有顯示出第四條資料。
create procedure p16() begin declare row_gid int ; declare row_name varchar(20); declare row_num int; declare have int default 1; declare getgoods cursor for select gid,num from goods; declare exit handler for NOT FOUND set have:= 0; open getgoods; repeat fetch getgoods into row_gid,row_num; until have = 0 end repeat; close getgoods; end$
輸出結果:
7、正確的遊標迴圈
在一些特殊的情況中,我們可以讀到的資料為空,或者壓根sql語句就有錯誤,我們不能避免出現這種情況,所以我們要正確的使用遊標迴圈操作。
首先應該建立遊標,然後開啟遊標後,應先手動進行fetch操作獲取到一行資料,然後再通過迴圈,在迴圈裡先做處理內容,後進行fetch操作。這樣如果在手動獲取資料的期間就沒有獲得到資料的話,就會執行have = 0,如果是repeat迴圈,然後進入repeat迴圈,先輸出null資料,最後又進行獲取,這樣執行到until時就會退出迴圈;如果是while迴圈,壓根就不進去while迴圈裡,就不會有任何1行輸出。
(1)repeat迴圈:
create procedure p17() begin declare row_gid int; declare row_name varchar(20); declare row_num int; declare have int default 1; declare getgoods cursor for select gid,num from goods where 0; declare continue handler for NOT FOUND set have:= 0; open getgoods; fetch getgoods into row_gid,row_num; repeat select row_name,row_num; fetch getgoods into row_gid,row_num; until have = 0 end repeat; close getgoods; end$
輸出結果:
(2)while迴圈:
create procedure p18() begin declare row_gid int; declare row_name varchar(20); declare row_num int; declare have int default 1; declare getgoods cursor for select gid,row_num; while have = 1 do select row_name,row_num; end while; close getgoods; end$
輸出結果:
更多關於MySQL相關內容感興趣的讀者可檢視本站專題:《MySQL查詢技巧大全》、《MySQL事務操作技巧彙總》、《MySQL儲存過程技巧大全》、《MySQL資料庫鎖相關技巧彙總》及《MySQL常用函式大彙總》
希望本文所述對大家MySQL資料庫計有所幫助。