博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[转]mysql 存储过程中使用多游标
阅读量:5790 次
发布时间:2019-06-18

本文共 3162 字,大约阅读时间需要 10 分钟。

From : 

mysql的存储过程可以很方便使用游标来实现一些功能,存储过程的写法大致如下:

先创建一张表,插入一些测试数据:

DROP TABLE IF EXISTS netingcn_proc_test;CREATE TABLE `netingcn_proc_test` (  `id` INTEGER(11) NOT NULL AUTO_INCREMENT,  `name` VARCHAR(20),  `password` VARCHAR(20),  PRIMARY KEY (`id`))ENGINE=InnoDB;insert into netingcn_proc_test(name, password) values('procedure1', 'pass1'),('procedure2', 'pass2'),('procedure3', 'pass3'),('procedure4', 'pass4');

下面就是一个简单存储过程的例子:

drop procedure IF EXISTS test_proc;delimiter //create procedure test_proc()begin	-- 声明一个标志done, 用来判断游标是否遍历完成	DECLARE done INT DEFAULT 0;	-- 声明一个变量,用来存放从游标中提取的数据	-- 特别注意这里的名字不能与由游标中使用的列明相同,否则得到的数据都是NULL	DECLARE tname varchar(50) DEFAULT NULL;	DECLARE tpass varchar(50) DEFAULT NULL;	-- 声明游标对应的 SQL 语句	DECLARE cur CURSOR FOR		select name, password from netingcn_proc_test;	-- 在游标循环到最后会将 done 设置为 1	DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;	-- 执行查询	open cur;	-- 遍历游标每一行	REPEAT		-- 把一行的信息存放在对应的变量中		FETCH cur INTO tname, tpass;		if not done then			-- 这里就可以使用 tname, tpass 对应的信息了			select tname, tpass;		end if; 	UNTIL done END REPEAT;	CLOSE cur;end//delimiter ;-- 执行存储过程call test_proc();

需要注意的是变量的声明、游标的声明和HANDLER声明的顺序不能搞错,必须是先声明变量,再申明游标,最后声明HANDLER。上述存储过程的例子中只使用了一个游标,那么如果要使用两个或者更多游标怎么办,其实很简单,可以这么说,一个怎么用两个就是怎么用的。例子如下:

drop procedure IF EXISTS test_proc_1;delimiter //create procedure test_proc_1()begin	DECLARE done INT DEFAULT 0;	DECLARE tid int(11) DEFAULT 0;	DECLARE tname varchar(50) DEFAULT NULL;	DECLARE tpass varchar(50) DEFAULT NULL;	DECLARE cur_1 CURSOR FOR		select name, password from netingcn_proc_test;	DECLARE cur_2 CURSOR FOR		select id, name from netingcn_proc_test;	DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;	open cur_1;	REPEAT		FETCH cur_1 INTO tname, tpass;		if not done then			select tname, tpass;		end if; 	UNTIL done END REPEAT;	CLOSE cur_1;	-- 注意这里,一定要重置done的值为 0	set done = 0;	open cur_2;	REPEAT		FETCH cur_2 INTO tid, tname;		if not done then			select tid, tname;		end if; 	UNTIL done END REPEAT;	CLOSE cur_2;end//delimiter ;call test_proc_1();

上述代码和第一个例子中基本一样,就是多了一个游标声明和遍历游标。这里需要注意的是,在遍历第二个游标前使用了set done = 0,因为当第一个游标遍历玩后其值被handler设置为1了,如果不用set把它设置为 0 ,那么第二个游标就不会遍历了。当然好习惯是在每个打开游标的操作前都用该语句,确保游标能真正遍历。当然还可以使用begin语句块嵌套的方式来处理多个游标,例如:

drop procedure IF EXISTS test_proc_2;delimiter //create procedure test_proc_2()begin	DECLARE done INT DEFAULT 0;	DECLARE tname varchar(50) DEFAULT NULL;	DECLARE tpass varchar(50) DEFAULT NULL;	DECLARE cur_1 CURSOR FOR		select name, password from netingcn_proc_test;	DECLARE cur_2 CURSOR FOR		select id, name from netingcn_proc_test;	DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;	open cur_1;	REPEAT		FETCH cur_1 INTO tname, tpass;		if not done then			select tname, tpass;		end if; 	UNTIL done END REPEAT;	CLOSE cur_1;	begin		DECLARE done INT DEFAULT 0;		DECLARE tid int(11) DEFAULT 0;		DECLARE tname varchar(50) DEFAULT NULL;		DECLARE cur_2 CURSOR FOR			select id, name from netingcn_proc_test;		DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;		open cur_2;		REPEAT			FETCH cur_2 INTO tid, tname;			if not done then				select tid, tname;			end if;	 	UNTIL done END REPEAT;		CLOSE cur_2;	end;end//delimiter ;call test_proc_2();
欢迎转载,转载请注明文章出处,谢谢!
你可能感兴趣的文章
Index 和Index Type 的区别
查看>>
转换wav为采样率16000的wav
查看>>
SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
查看>>
整合企业架构的技术点
查看>>
Java编程代码性能优化总结
查看>>
深度解析JavaScript事件对象
查看>>
用Python爬取优酷弹幕数据并做成词云,"人"云亦云
查看>>
外企面试,哪有你想象的那么难!(已收埃森哲、NTTDATA等8家外企offer)
查看>>
华为云服务器实战 之 Gitlab安装与配置使用
查看>>
数据库性能测试
查看>>
MongoDB
查看>>
OSChina 周日乱弹——如何请假不被老板骂
查看>>
OSChina 周四乱弹 —— 80后的巅峰,竟然是他!
查看>>
OSChina 周一乱弹 —— 你会被局长这样的女孩子拒绝的
查看>>
初识移动web
查看>>
通过反射处理委托
查看>>
iOS 界面上绘制不同字体 颜色 大小的字符串
查看>>
mvc:resource 知识点
查看>>
Springboot 打包 外部jar system
查看>>
Android 开发之 MP4 文件转 GIF 文件详解
查看>>