mysql游標例子

創(chuàng)建游標
首先在MySql中創(chuàng)建一張數(shù)據(jù)表:

CREATE TABLE IF NOT EXISTS store (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(20) NOT NULL,
count int(11) NOT NULL DEFAULT '1',
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7;

INSERT INTO store (id, name, count) VALUES
(1, 'android', 15),
(2, 'iphone', 14),
(3, 'iphone', 20),
(4, 'android', 5),
(5, 'android', 13),
(6, 'iphone', 13);

我們現(xiàn)在要用存儲過程做一個功能,統(tǒng)計iphone的總庫存是多少知允,并把總數(shù)輸出到控制臺迫横。

--在windows系統(tǒng)中寫存儲過程時茉稠,如果需要使用declare聲明變量,需要添加這個關鍵字谓晌,否則會報錯吸重。
delimiter //
drop procedure if exists StatisticStore;
CREATE PROCEDURE StatisticStore()
BEGIN
--創(chuàng)建接收游標數(shù)據(jù)的變量
declare c int;
declare n varchar(20);
--創(chuàng)建總數(shù)變量
declare total int default 0;
--創(chuàng)建結束標志變量
declare done int default false;
--創(chuàng)建游標
declare cur cursor for select name,count from store where name = 'iphone';
--指定游標循環(huán)結束時的返回值
declare continue HANDLER for not found set done = true;
--設置初始值
set total = 0;
--打開游標
open cur;
--開始循環(huán)游標里的數(shù)據(jù)
read_loop:loop
--根據(jù)游標當前指向的一條數(shù)據(jù)
fetch cur into n,c;
--判斷游標的循環(huán)是否結束
if done then
leave read_loop; --跳出游標循環(huán)
end if;
--獲取一條數(shù)據(jù)時,將count值進行累加操作血巍,這里可以做任意你想做的操作,
set total = total + c;
--結束游標循環(huán)
end loop;
--關閉游標
close cur;

--輸出結果  
select total;  

END;
--調(diào)用存儲過程
call StatisticStore();

fetch是獲取游標當前指向的數(shù)據(jù)行珊随,并將指針指向下一行述寡,當游標已經(jīng)指向最后一行時繼續(xù)執(zhí)行會造成游標溢出。使用loop循環(huán)游標時叶洞,他本身是不會監(jiān)控是否到最后一條數(shù)據(jù)了鲫凶,像下面代碼這種寫法,就會造成死循環(huán)衩辟;

read_loop:loop
fetch cur into n,c;
set total = total+c;
end loop;

在MySql中螟炫,造成游標溢出時會引發(fā)mysql預定義的NOT FOUND錯誤,所以在上面使用下面的代碼指定了當引發(fā)not found錯誤時定義一個continue 的事件艺晴,指定這個事件發(fā)生時修改done變量的值昼钻。

declare continue HANDLER for not found set done = true;

所以在循環(huán)時加上了下面這句代碼:

--判斷游標的循環(huán)是否結束
if done then
leave read_loop; --跳出游標循環(huán)
end if;

如果done的值是true,就結束循環(huán)封寞。繼續(xù)執(zhí)行下面的代碼然评。

使用方式
游標有三種使用方式:第一種就是上面的實現(xiàn),使用loop循環(huán)狈究;第二種方式如下碗淌,使用while循環(huán):

drop procedure if exists StatisticStore1;
CREATE PROCEDURE StatisticStore1()
BEGIN
declare c int;
declare n varchar(20);
declare total int default 0;
declare done int default false;
declare cur cursor for select name,count from store where name = 'iphone';
declare continue HANDLER for not found set done = true;
set total = 0;
open cur;
fetch cur into n,c;
while(not done) do
set total = total + c;
fetch cur into n,c;
end while;

close cur;  
select total;  

END;

call StatisticStore1();

第三種方式是使用repeat執(zhí)行:

drop procedure if exists StatisticStore2;
CREATE PROCEDURE StatisticStore2()
BEGIN
declare c int;
declare n varchar(20);
declare total int default 0;
declare done int default false;
declare cur cursor for select name,count from store where name = 'iphone';
declare continue HANDLER for not found set done = true;
set total = 0;
open cur;
repeat
fetch cur into n,c;
if not done then
set total = total + c;
end if;
until done end repeat;
close cur;
select total;
END;

call StatisticStore2();

游標嵌套
在mysql中,每個begin end 塊都是一個獨立的scope區(qū)域,由于MySql中同一個error的事件只能定義一次贯莺,如果多定義的話在編譯時會提示Duplicate handler declared in the same block。

drop procedure if exists StatisticStore3;
CREATE PROCEDURE StatisticStore3()
BEGIN
declare _n varchar(20);
declare done int default false;
declare cur cursor for select name from store group by name;
declare continue HANDLER for not found set done = true;
open cur;
read_loop:loop
fetch cur into _n;
if done then
leave read_loop;
end if;
begin
declare c int;
declare n varchar(20);
declare total int default 0;
declare done int default false;
declare cur cursor for select name,count from store where name = 'iphone';
declare continue HANDLER for not found set done = true;
set total = 0;
open cur;
iphone_loop:loop
fetch cur into n,c;
if done then
leave iphone_loop;
end if;
set total = total + c;
end loop;
close cur;
select _n,n,total;
end;
begin
declare c int;
declare n varchar(20);
declare total int default 0;
declare done int default false;
declare cur cursor for select name,count from store where name = 'android';
declare continue HANDLER for not found set done = true;
set total = 0;
open cur;
android_loop:loop
fetch cur into n,c;
if done then
leave android_loop;
end if;
set total = total + c;
end loop;
close cur;
select _n,n,total;
end;
begin

end;  
end loop;  
close cur;  

END;

call StatisticStore3();

上面就是實現(xiàn)一個嵌套循環(huán)宁改,當然這個例子比較牽強缕探。湊合看看就行。还蹲。

動態(tài)SQL
Mysql 支持動態(tài)SQL的功能爹耗,

set @sqlStr='select * from table where condition1 = ?';
prepare s1 for @sqlStr;
--如果有多個參數(shù)用逗號分隔
execute s1 using @condition1;
--手工釋放,或者是 connection 關閉時谜喊, server 自動回收
deallocate prepare s1;

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末潭兽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子斗遏,更是在濱河造成了極大的恐慌山卦,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诵次,死亡現(xiàn)場離奇詭異账蓉,居然都是意外死亡,警方通過查閱死者的電腦和手機逾一,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進店門铸本,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人遵堵,你說我怎么就攤上這事箱玷。” “怎么了陌宿?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵锡足,是天一觀的道長。 經(jīng)常有香客問我壳坪,道長舱污,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任弥虐,我火速辦了婚禮扩灯,結果婚禮上,老公的妹妹穿的比我還像新娘霜瘪。我一直安慰自己兴溜,他們只是感情好,可當我...
    茶點故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布均抽。 她就那樣靜靜地躺著吉嫩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上顾患,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天番捂,我揣著相機與錄音,去河邊找鬼江解。 笑死设预,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的犁河。 我是一名探鬼主播鳖枕,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼桨螺!你這毒婦竟也來了宾符?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤灭翔,失蹤者是張志新(化名)和其女友劉穎魏烫,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肝箱,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡则奥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了狭园。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片读处。...
    茶點故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖唱矛,靈堂內(nèi)的尸體忽然破棺而出罚舱,到底是詐尸還是另有隱情,我是刑警寧澤绎谦,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布管闷,位于F島的核電站,受9級特大地震影響窃肠,放射性物質(zhì)發(fā)生泄漏包个。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一冤留、第九天 我趴在偏房一處隱蔽的房頂上張望碧囊。 院中可真熱鬧,春花似錦纤怒、人聲如沸糯而。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽熄驼。三九已至像寒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瓜贾,已是汗流浹背诺祸。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留祭芦,地道東北人筷笨。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像实束,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子逊彭,可洞房花燭夜當晚...
    茶點故事閱讀 44,652評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 背景 一年多以前我在知乎上答了有關LeetCode的問題, 分享了一些自己做題目的經(jīng)驗咸灿。 張土汪:刷leetcod...
    土汪閱讀 12,743評論 0 33
  • 什么是SQL數(shù)據(jù)庫: SQL是Structured Query Language(結構化查詢語言)的縮寫。SQL是...
    西貝巴巴閱讀 1,810評論 0 10
  • 1.PLSQL入門 Oracle數(shù)據(jù)庫對SQL進行了擴展,然后加入了一些編程語言的特點,可以對SQL的執(zhí)行過程進行...
    隨手點燈閱讀 598評論 0 8
  • 文/天水石逸 ——題記:夜色下我靜靜地撫摸著胸口,傳來陣陣的疼痛囊榜,或飄零审胸,或孤獨。在一頁紙上卸勺,我無可奈何地記錄了行...
    天水石逸閱讀 746評論 0 1
  • 我走在河邊砂沛。時近黃昏,秋波在風中籟籟作響曙求。 枯草繞足羈絆流光步履碍庵。鳴雁聲過。 我在河邊行走悟狱,也不知道為什么静浴。 有人...
    河南張鵬閱讀 259評論 2 1