日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

mysql 为游标赋值_mysql 存储过程之游标

發(fā)布時(shí)間:2025/3/19 数据库 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql 为游标赋值_mysql 存储过程之游标 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

游標(biāo)按我的理解就是用在sql編程中對(duì)查詢結(jié)果集的解析,類(lèi)比jdbc中的resultset對(duì)象。FETCH 一行游標(biāo)指針就往下面移動(dòng)一行,直到所有行被遍歷完成。

游標(biāo)的使用分為4步:

1、定義游標(biāo),指定游標(biāo)名和查詢sql語(yǔ)句

2、打開(kāi)游標(biāo)

3、fetch 獲取數(shù)據(jù),賦值給變量

4、關(guān)閉游標(biāo)

基本使用

1、數(shù)據(jù)準(zhǔn)備

CREATE TABLE `goods` (

`gid` int(11) NOT NULL COMMENT '主鍵',

`name` char(5) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '商品',

`num` int(11) NULL DEFAULT NULL COMMENT '庫(kù)存',

PRIMARY KEY (`gid`) USING BTREE

) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------

-- Records of goods

-- ----------------------------

INSERT INTO `goods` VALUES (1, 'cat', 34);

INSERT INTO `goods` VALUES (2, 'dog', 0);

INSERT INTO `goods` VALUES (3, 'pig', 12);

2、定義存儲(chǔ)過(guò)程,簡(jiǎn)單使用下游標(biāo)

CREATE DEFINER="root"@"%" PROCEDURE "p5"()

BEGIN

# 定義接受sql數(shù)據(jù)的變量

DECLARE row_gid int;

DECLARE row_name varchar(20);

DECLARE row_num int;

# 定義游標(biāo)

DECLARE getgoods CURSOR FOR

select gid, name, num from goods;

# 打開(kāi)游標(biāo)

OPEN getgoods;

# 獲取數(shù)據(jù),使用一次FETCH就是獲取一行

# 注意需要按列順序的順序賦值

FETCH getgoods INTO row_gid, row_name, row_num;

select row_gid, row_name, row_num;

FETCH getgoods INTO row_gid, row_name, row_num;

select row_gid, row_name, row_num;

FETCH getgoods INTO row_gid, row_name, row_num;

select row_gid, row_name, row_num;

FETCH getgoods INTO row_gid, row_name, row_num;

select row_gid, row_name, row_num;

# 關(guān)閉游標(biāo)

CLOSE getgoods;

END

執(zhí)行下 CALL p5(); 可以看到有三個(gè)結(jié)果集

image.png

然而我FETCH 了4次,只有3行。那么產(chǎn)生了游標(biāo)越界錯(cuò)誤。

1329 - No data - zero rows fetched, selected, or processed

使用REPEAT循環(huán)去FETCH 數(shù)據(jù)

使用循環(huán)去遍歷游標(biāo),將查詢sql所有的數(shù)據(jù)取出。使用count(*)總記錄數(shù)去做循環(huán)的判斷條件。若循環(huán)計(jì)數(shù)器大于等于總記錄數(shù)則停止循環(huán)。

CREATE DEFINER="root"@"%" PROCEDURE "p6"()

BEGIN

# 定義接受sql數(shù)據(jù)的變量

DECLARE row_gid int;

DECLARE row_name varchar(20);

DECLARE row_num int;

# 總行數(shù)

DECLARE cnt INT DEFAULT 0;

# 循環(huán)變量i

DECLARE i INT DEFAULT 0;

# 定義游標(biāo)

DECLARE getgoods CURSOR FOR select gid, name, num from goods;

# 查詢總行數(shù)并賦值給 cnt

# 注意這句話一定要放到定義游標(biāo)的下面,否則報(bào)錯(cuò)創(chuàng)建存儲(chǔ)過(guò)程失敗!

SELECT COUNT(*) INTO cnt FROM goods;

# 打開(kāi)游標(biāo)

OPEN getgoods;

# 開(kāi)始循環(huán)

REPEAT

SET i := i+1;

FETCH getgoods INTO row_gid, row_name, row_num;

select row_gid, row_name, row_num;

UNTIL i>=cnt END REPEAT;

# 循環(huán)結(jié)束

# 關(guān)閉游標(biāo)

CLOSE getgoods;

END

使用游標(biāo)監(jiān)聽(tīng)器 continue handler 和 exit handler 來(lái)完善游標(biāo)的遍歷

上面遍歷游標(biāo),防止越界讀取。使用的是count(*) 額外的去發(fā)出一條查詢,有著額外的性能損耗。事實(shí)上不需要這樣,mysql游標(biāo)有提供它的方式。

我們可以使用 handler 監(jiān)聽(tīng)器,在該監(jiān)聽(tīng)器中定義sql。等到游標(biāo)被遍歷完便會(huì)自動(dòng)執(zhí)行這個(gè)sql。那么我們可以使用一個(gè)變量,初始化為0,默認(rèn)未遍歷完。在監(jiān)聽(tīng)器sql中寫(xiě)入設(shè)置變量值為1。然后在循環(huán)中使用該變量判斷即可

定義監(jiān)聽(tīng)器

DECLARE CONTINUE HANDLER FOR NOT FOUND set flag :=1;

CREATE DEFINER="root"@"%" PROCEDURE "p7"()

BEGIN

DECLARE row_gid int;

DECLARE row_name varchar(20);

DECLARE row_num int;

# 定義循環(huán)退出標(biāo)志符變量

DECLARE flag INT DEFAULT 0;

DECLARE getgoods CURSOR FOR select gid, name, num from goods;

# 定義監(jiān)聽(tīng)器

DECLARE CONTINUE HANDLER FOR NOT FOUND set flag :=1;

OPEN getgoods;

REPEAT

FETCH getgoods INTO row_gid, row_name, row_num;

select row_gid, row_name, row_num;

UNTIL flag=1 END REPEAT;

CLOSE getgoods;

END

執(zhí)行下 call p7();發(fā)現(xiàn)只有3行記錄卻放回4個(gè)結(jié)果集。而且第3個(gè)和第4個(gè)結(jié)果集是相同的。這是一個(gè)問(wèn)題。

image.png

第4次執(zhí)行fetch時(shí)是沒(méi)數(shù)據(jù)的,那么觸發(fā)not found set flag:=1 ,然后continue一下繼續(xù)執(zhí)行后面的sql語(yǔ)句,那么select row_gid, row_name, row_num;又被執(zhí)行一次,最后一行就被執(zhí)行了2次。

若not found set flag:=1 觸發(fā)后,后面的select不再執(zhí)行即可。那么我們可以使用 exit代替continute,exit和continute的區(qū)別是:exit觸發(fā)后后面的語(yǔ)句不再執(zhí)行!

那么使用exit可以完美解決如下:

CREATE DEFINER="root"@"%" PROCEDURE "p7"()

BEGIN

DECLARE row_gid int;

DECLARE row_name varchar(20);

DECLARE row_num int;

# 定義循環(huán)退出標(biāo)志符變量

DECLARE flag INT DEFAULT 0;

DECLARE getgoods CURSOR FOR select gid, name, num from goods;

# 定義EXIT 監(jiān)聽(tīng)器

DECLARE EXIT HANDLER FOR NOT FOUND set flag :=1;

OPEN getgoods;

REPEAT

FETCH getgoods INTO row_gid, row_name, row_num;

select row_gid, row_name, row_num;

UNTIL flag=1 END REPEAT;

CLOSE getgoods;

END

執(zhí)行如下,3個(gè)返回集沒(méi)問(wèn)題

image.png

除了continue 和exit還有一種undo handler 。undo的功能是觸發(fā)后,前面的語(yǔ)句撤銷(xiāo),目前mysql不支持

除了使用exit解決,continue 基礎(chǔ)上也是可以的。讓如果一定要使用continue 的話就需要修改下邏輯,提前FETCH 下了。為了避免查詢結(jié)果為空而導(dǎo)致返回空結(jié)果集,就需要使用while循環(huán)代替pepeat循環(huán)。因?yàn)閜epeat循環(huán)類(lèi)似do while,它總是先執(zhí)行一次循環(huán)體再判斷的。

那么,while加上continue handler 的正確遍歷方式如下:

CREATE DEFINER="root"@"%" PROCEDURE "p7"()

BEGIN

DECLARE row_gid int;

DECLARE row_name varchar(20);

DECLARE row_num int;

# 定義循環(huán)退出標(biāo)志符變量

DECLARE flag INT DEFAULT 0;

DECLARE getgoods CURSOR FOR select gid, name, num from goods;

# 定義監(jiān)聽(tīng)器

DECLARE CONTINUE HANDLER FOR NOT FOUND set flag :=1;

OPEN getgoods;

# 提前FETCH下

FETCH getgoods INTO row_gid, row_name, row_num;

# 換成while循環(huán),就不會(huì)當(dāng)返回集為null時(shí)查出數(shù)據(jù)為空的了

# 注意while循環(huán)的循環(huán)條件為true時(shí)才進(jìn)入循環(huán)

WHILE flag=0 DO

select row_gid, row_name, row_num;

FETCH getgoods INTO row_gid, row_name, row_num;

END WHILE;

CLOSE getgoods;

END

總結(jié)

以上是生活随笔為你收集整理的mysql 为游标赋值_mysql 存储过程之游标的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产又粗又猛又爽又黄的视频小说 | 成人wwxx免费观看 | 男人的天堂视频 | 一级特黄aa大片免费播放 | 国产激情久久 | 射婷婷| 中文国语毛片高清视频 | 久久精品国产亚洲AV高清综合 | 国产91在线播放精品91 | 亚洲三级视频在线观看 | 九九综合九九 | 亚洲网站免费 | 午夜av在线免费观看 | 国产swag在线| 日韩中文字幕网站 | 亚洲图片三区 | 国产一级片免费在线观看 | 日本美女黄视频 | 四虎成人精品永久免费av九九 | 国产精品国产a级 | 蜜桃成人免费视频 | www.五月天婷婷| 夜夜操天天干 | 精品久久久久久久免费人妻 | 国产视频一区二区三区四区 | 国产精品夜夜爽张柏芝 | 日韩在线激情视频 | 夜夜av| 贝利弗山的秘密在线观看 | 人妻熟女一区二区三区app下载 | 日韩精品在线观看AV | 天堂网成人 | 国产福利视频一区二区 | 日本欧美一区二区三区不卡视频 | 久久性生活视频 | 精品一区三区 | 国产毛片久久久久久久 | 综合色综合 | 性欧美大战久久久久久久 | 免费成人深夜 | av网站在线观看免费 | 精品日本一区二区三区 | 中文字幕日韩欧美一区二区 | 人妻熟女一区二区三区app下载 | 国产欧美一区二区三区精品酒店 | 337p粉嫩大胆色噜噜狠狠图片 | 99热99热 | 日韩精品一区三区 | 欧美成人aaaaa | 精久久久久久 | 五月天色站 | 久久久久精| 特级西西www444人体聚色 | 久久1024| 国产综合一区二区 | 91蜜桃传媒精品久久久一区二区 | 囯产精品一品二区三区 | 亚洲一区二区在线免费观看 | 国产成人精品免费视频 | 国产日韩一区二区三区在线观看 | 欧美不卡视频 | 日韩欧美一卡 | 九色一区 | 在线播放日韩av | 亚洲码欧美码一区二区三区 | 风间由美一区 | 美国伊人网 | 色天天综合网 | 亲女禁h啪啪宫交 | av在线资源站 | 欧美亚洲图片小说 | 自拍啪啪 | 岛国大片在线免费观看 | 成年人在线视频 | 欧美久久一区二区三区 | 成人一级网站 | 中文字幕久久熟女蜜桃 | 中国特级黄色大片 | 中文字幕一区二区免费 | 久久爰| 欧美性爱视频久久 | av资源免费观看 | 羞羞色院91蜜桃 | 久久久久国产精品一区二区 | 精品自拍偷拍 | 免费黄网站在线 | 激情网久久 | 欧美性受xxxx黑人猛交88 | 乳罩脱了喂男人吃奶视频 | 天天操夜夜操视频 | 日本特黄特色aaa大片免费 | 亚洲国产第一区 | 国产精品久久久久久亚洲 | 激情女主播 | a天堂在线视频 | 青青在线 | 午夜精品免费观看 | 欧美日韩观看 | 日韩在线观看不卡 |