MySQL游標(biāo)的使用

創(chuàng)建游標(biāo)

首先在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)在要用存儲(chǔ)過(guò)程做一個(gè)功能碘耳,統(tǒng)計(jì)iphone的總庫(kù)存是多少,并把總數(shù)輸出到控制臺(tái)框弛。

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

    --輸出結(jié)果
    select total;
END;
--調(diào)用存儲(chǔ)過(guò)程
call StatisticStore();

fetch是獲取游標(biāo)當(dāng)前指向的數(shù)據(jù)行,并將指針指向下一行膝擂,當(dāng)游標(biāo)已經(jīng)指向最后一行時(shí)繼續(xù)執(zhí)行會(huì)造成游標(biāo)溢出虑啤。
使用loop循環(huán)游標(biāo)時(shí),他本身是不會(huì)監(jiān)控是否到最后一條數(shù)據(jù)了架馋,像下面代碼這種寫(xiě)法狞山,就會(huì)造成死循環(huán);

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

在MySql中叉寂,造成游標(biāo)溢出時(shí)會(huì)引發(fā)mysql預(yù)定義的NOT FOUND錯(cuò)誤萍启,所以在上面使用下面的代碼指定了當(dāng)引發(fā)not found錯(cuò)誤時(shí)定義一個(gè)continue 的事件,指定這個(gè)事件發(fā)生時(shí)修改done變量的值屏鳍。

declare continue HANDLER for not found set done = true; 

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

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

如果done的值是true勘纯,就結(jié)束循環(huán)。繼續(xù)執(zhí)行下面的代碼钓瞭。

使用方式
游標(biāo)有三種使用方式:第一種就是上面的實(shí)現(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;

第三種方式是使用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;

游標(biāo)嵌套

在mysql中超埋,每個(gè)begin end 塊都是一個(gè)獨(dú)立的scope區(qū)域,由于MySql中同一個(gè)error的事件只能定義一次佳鳖,如果多定義的話(huà)在編譯時(shí)會(huì)提示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();

轉(zhuǎn)載:http://blog.csdn.net/liguo9860/article/details/50848216

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市系吩,隨后出現(xiàn)的幾起案子来庭,更是在濱河造成了極大的恐慌,老刑警劉巖穿挨,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件月弛,死亡現(xiàn)場(chǎng)離奇詭異肴盏,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)帽衙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)菜皂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人厉萝,你說(shuō)我怎么就攤上這事恍飘。” “怎么了谴垫?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵章母,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我翩剪,道長(zhǎng)乳怎,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任前弯,我火速辦了婚禮蚪缀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘博杖。我一直安慰自己椿胯,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布剃根。 她就那樣靜靜地躺著,像睡著了一般前方。 火紅的嫁衣襯著肌膚如雪狈醉。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,598評(píng)論 1 305
  • 那天惠险,我揣著相機(jī)與錄音苗傅,去河邊找鬼。 笑死班巩,一個(gè)胖子當(dāng)著我的面吹牛渣慕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播抱慌,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼逊桦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了抑进?” 一聲冷哼從身側(cè)響起强经,我...
    開(kāi)封第一講書(shū)人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎寺渗,沒(méi)想到半個(gè)月后匿情,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體兰迫,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年炬称,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了汁果。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡玲躯,死狀恐怖据德,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情府蔗,我是刑警寧澤晋控,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站姓赤,受9級(jí)特大地震影響赡译,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜不铆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一蝌焚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧誓斥,春花似錦只洒、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至距芬,卻和暖如春涝开,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背框仔。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工舀武, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人离斩。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓银舱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親跛梗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子寻馏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

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