mysql存储过程游标的创建_mysql存储过程之游标

1、什么是游标?

游标就类似于迭代器或者指针之类的东西,它指向第一条数据库中的记录,每取一次记录则游标向后移动一位

2、游标的4个部分

1、declare 申明  -- declare 游标名 cursor for select statement

2、open 打开     --open 游标名

3、fetch 取值    --fetch 游标名 into var1,var2,[...]

4、close 关闭--close 游标名

3、游标要和select语句配合使用

declare c cursor for select * from user

这句话就表示游标c指向select * from user查询结果集的第一条记录(该记录还未从数据库中取出,这儿可以写逻辑决定要不要返回该记录给调用程序,每取一次,游标就向后移动一位)

4、定义游标并循环游标(推荐使用repeat循环)

XML Code

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

create procedure use_cursor()

begin

declare row_id int default 0;

declare row_name varchar(20) default '';

declare flag int default 0;

declare c cursor for select id,name from t1;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET FLAG=1;

open c;

repeat

fetch c into row_id,row_name;

select concat('id=',row_id,' name=',row_name);

until flag

end repeat;

close c;

end$$

5、发现最后一条记录打印了两次???这是为什么?

这是因为当游标指向最后一条记录时,把row_id,row_name赋值为10,name-10,当下一次执行时发现没有数据可取,

所以就出发了前面定义的handler使flag=1,但是这是一个continue类型handler即当触发该handler后程序依然继续往下

执行,由于本次没有数据可取,故没有给row_id和row_name赋值,就接着把上一次row_id和row_name打印了出来

这是为什么会出现两次的原因

6、解决这个问题有两种办法

6.1最简单的办法是使用exit类型的handler即当触发该类型的handler时程序不在往下执行也就是说直接跳出了循环(存储过程)

个人不推荐这种做法,如果后面还有代码要执行则通过这种方式就不能实现

XML Code

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

create procedure use_e_handler()

begin

declare row_id int default 0;

declare row_name varchar(20) default '';

declare flag int default 0;

declare c cursor for select id,name from t1;

DECLARE exit HANDLER FOR NOT FOUND SET FLAG=1;

open c;

repeat

fetch c into row_id,row_name;

until flag

end repeat;

close c;

select 'continue over...';

end$$

6.2手动检测flag标志的值,如果发现触发了handler就手动离开循环

XML Code

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

create procedure use_cursor_e()

begin

declare row_id int default 0;

declare row_name varchar(20) default '';

declare flag int default 0;

declare c cursor for select id,name from t1;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET FLAG=1;

open c;

r:repeat

fetch c into row_id,row_name;

if flag  then

leave r;

end if;

select concat('id=',row_id,' name=',row_name);

until flag

end repeat r;

close c;

end$$

7,存储过程之间的通信(唯一的方法是创建临时表)

--创建一个创建临时表的存储过程

XML Code

1

2

3

4

create procedure p_producer()

begin

create temporary table t2 as select * from t1;

end$$ --创建一个用于消费前一个存储过程创建的表的存储过程

XML Code

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

create procedure p_consumer() begin     declare flag int default 0;     declare row_id int default 0;     declare row_name varchar(10) default '';     declare c cursor for select id,name from t2;     declare continue handler for not found set flag=1;     open c;     r:repeat          fetch c into row_id,row_name;         if flag then              leave r;         end if;         select row_id,row_name;         until flag     end repeat r; end$$

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值