关于mysql写触发器中运用游标的问题。

原创 2015年07月08日 20:55:02


Mysql中游标的用法现在提供的还很特别,虽然使用起来没有PL/SQL那么顺手,不过使用上大致上还是一样,本文将详细介绍一下,需要了解的朋友可以参考下

首先定义游标(不论声明变量还是游标还是其他的什么都要在你执行任何操作的前面,不然会报错的)

declare cur_count cursor for select seqname, value from sys_sequence;

 (这里如果用到变量的话就直接 在数据库查,因为这里是在声明,你的任何变量现在都是没有值得)

使用游标
open cur_count ;
fetch获得数据 给_seqname, _value
fetch cursor into _seqname, _value;
关闭游标
close cur_count ;
不过这都是针对cursor的操作而已,和PL/SQL没有什么区别吧,不过光是了解到这个是根本不足以写出Mysql的fetch过程的,还要了解其他的更深入的知识,我们才能真正的写出好的游标使用的procedure
首先fetch离不开循环语句,那么先了解一下循环吧。
我一般使用Loop和while觉得比较清楚,而且代码简单。


这里使用Loop为例

fetchSeqLoop:Loop 
fetch cursor into _seqname, _value; 
end Loop; 



现在是死循环,还没有退出的条件,那么在这里和oracle有区别,Oracle的PL/SQL的指针有个隐性变量%notfound,Mysql是通过一个Error handler的声明来进行判断的,
declare continue handler for Not found (do some action);
在Mysql里当游标遍历溢出时,会出现一个预定义的NOT FOUND的Error,我们处理这个Error并定义一个continue的handler就可以叻,关于Mysql Error handler可以查询Mysql手册定义一个flag,在NOT FOUND,标示Flag,在Loop里以这个flag为结束循环的判断就可以叻。

declare fetchSeqOk boolean; ## define the flag for loop judgement 
declare _seqname varchar(50); ## define the varient for store the data 
declare _value bigint(20); 
declare fetchSeqCursor cursor for select seqname, value from sys_sequence;## define the cursor 
declare continue handler for NOT FOUND set fetchSeqOk = true; ## define the continue handler for not 
found flag 
set fetchSeqOk = false; 
open fetchSeqCursor; 
fetchSeqLoop:Loop 
if fetchSeqOk then 
leave fetchSeqLoop; 
else 
fetch cursor into _seqname, _value; 
select _seqname, _value; 
end if; 
end Loop; 
close fetchSeqCursor; 

这就是一个完整的过程叻,那么会思考的人一般在这里都会思考,如果是这样的话,怎样做嵌套的游标循环叻,这里可以根据statement block的scope实现叻,Mysql里通过begin end来划分一个statement block,在block里定义的变量范围也在这个block里,所以关于嵌套的游标循环我们可以多加一个begin end来区分他们所对应的error handler(注意在Mysql里同一个error的handler只能定义一次,多定义的话,在compile的过程中会提示里duplicate handler defination,所以NOT FOUND的handler就只能定义一次),在一个begin end里定义这个里面游标的NOT FOUND handler,

declare fetchSeqOk boolean; ## define the flag for loop judgement 
declare _seqname varchar(50); ## define the varient for store the data 
declare _value bigint(20); 
declare fetchSeqCursor cursor for select seqname, value from sys_sequence;## define the cursor 
declare continue handler for NOT FOUND set fetchSeqOk = true; ## define the continue handler for not 
found flag 
set fetchSeqOk = false; 
open fetchSeqCursor; 
fetchSeqLoop:Loop 
if fetchSeqOk then 
leave fetchSeqLoop; 
else 
fetch cursor into _seqname, _value; 
begin 
declare fetchSeqOk boolean default 'inner'; 
declare cursor2 cursor for select .... from ...;## define the cursor 
declare continue handler for NOT FOUND set fetchSeqOk = true; ## define the continue handler for n 
ot 
set fetchSeqOk = false; 
open cursor2; 
fetchloop2 loop 
if fetchSeqOk then 
else 
end if; 
end loop; 
close cursor2; 
end; 
end if; 
end Loop; 
close fetchSeqCursor; 

我把自己写的触发器写到这里,供大家参考,也作为我的一个备忘吧。

begin 
#声明一个变量用于while循环
DECLARE i int;
declare fetchSeqOk boolean; 
declare pid int; 
  #声明一个游标
declare  cur_count cursor for select  object_id from mot_term_relationships where term_taxonomy_id = (select term_taxonomy_id   from mot_term_taxonomy  where term_id=old.term_id);
declare continue handler for NOT FOUND set fetchSeqOk = true; #define the continue handler for not found flag ;
set fetchSeqOk = false; 

/*得到删除term的父类  @parentId 父类的term_id*/
select parent into @parentId   from mot_term_taxonomy  where term_id=old.term_id;
#你删除的term对应的term_taxonomy_id     @term_taxonomy_id_old
select term_taxonomy_id into @term_taxonomy_id_old  from mot_term_taxonomy  where term_id=old.term_id;


if @parentId != '0'  then
	 /*得到父类对应的term_taxonomy_Id,赋值给被删除term的文章,吧term对应的文章移动到它对应的父类下    @term_taxonomy_id_new 父类的term_taxonomy_id*/
	select  term_taxonomy_id  into @term_taxonomy_id_new  from mot_term_taxonomy  where term_id=@parentId;
	/*如果这个term有子分类 子分类的级别分别向上提一级,就是他的第一级子分类的parent id改为删除term的parent id*/
	update mot_term_taxonomy set parent=@parentId where parent=old.term_id;
	/*把term对应的文章移动到它对应的父类下*/ 
	/*循环查出这个分类对应的文章*/
	
	#打开游标
	open cur_count;
	#游标循环
	cur_count:LOOP
	FETCH cur_count INTO pid;
	 #游标出口
	if fetchSeqOk THEN
	  leave cur_count;  
	 #利用游标做的操作
	else
	 /*判断父类是否已经有这篇文章了如果有了就不给做任何操作,如果没有则可以需改(不然会出现主键重复的问题)*/
	  select count(*) into @count from mot_term_relationships  where term_taxonomy_id =@term_taxonomy_id_new and object_id=pid;
	  IF  @count<>1 THEN

		update mot_term_relationships set term_taxonomy_id = @term_taxonomy_id_new where term_taxonomy_id = @term_taxonomy_id_old and object_id=pid;

	  end if;
	end if;
	end LOOP;
	CLOSE cur_count;

	else 
			 /*如果对应的parent id为0 则移动到默认分类下。*/
			 /*从option表中查出默认分类的term_id*/
			 select option_value into @term_id_def from mot_options where option_name='default_category';
			 /*根据查出来的term_id 查出对应的term_taxonomy_id */
			 select  term_taxonomy_id into @term_taxonomy_id_new  from mot_term_taxonomy  where term_id=@term_id_def ;
			 /*如果这个term有子分类 子分类的级别分别向上提一级,就是他的第一级子分类的parent id改为删除term的parent id*/
			 update mot_term_taxonomy set parent=@parentId where parent=old.term_id;
			 /*把对应的post移动到默认分类下。*/
			 update mot_term_relationships set term_taxonomy_id = @term_taxonomy_id_new where term_taxonomy_id=@term_taxonomy_id_old;
	end if;
         /*对应删除mot_term_taxonomy 的记录*/
        delete from mot_term_taxonomy   where  term_id=old.term_id;
end



版权声明:转载请注明出处哦!!

关于游标的应用实例

在最近的开发过程中,底层数据库的逻辑稍微有些复杂,在这个过程中涉及到了游标的使用,结合项目的逻辑我简单描述一下游标的使用,如果能对您有一点点的帮助,我将非常高兴,有不合理之处,欢迎大神随时指出。  ...
  • zt15732621796
  • zt15732621796
  • 2016年12月28日 12:40
  • 264

ORACLE PL/SQL语法应用:游标,存储过程,触发器,函数

--游标 --do while declare    cursor c is select * from t_t_student order by id;   v_record c%rowtype; ...
  • Eric_ley
  • Eric_ley
  • 2017年02月16日 17:46
  • 445

Oracle,day9,游标和触发器

前言:昨天去中移在线面试了,问的东西很底层,回答的并不好,哎,又没戏了赶脚。。而且还晕车了,昨天什么都没有学,讲道理爱学习的我应该是非常懊恼的,但是为什么心里有一种莫名的快感[爽!],哈哈,不能颓废啊...
  • holy516203
  • holy516203
  • 2016年12月13日 20:16
  • 544

MySql中游标的定义与使用方式

创建游标 首先在MySql中创建一张数据表: CREATE TABLE IF NOT EXISTS `store` ( `id` int(11) NOT NULL AUTO_INCREMENT, ...
  • liguo9860
  • liguo9860
  • 2016年03月10日 18:42
  • 26615

mysql中游标的运用

游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制;游标充当指针的作用;尽管游标能遍历结果中的所有行,但他一次只指向一行。...
  • u013030601
  • u013030601
  • 2016年12月27日 16:14
  • 3199

存储过程中遍历游标的三种方式(For,Fetch,While)

我是初学数据库编程,在这里谈谈我对游标的理解,如果有什么理解不对的,还希望路过的大牛们指导一番! 游标其实就是结果集,而在实际开发中,常用的是for循环去遍历游标。直接上代码吧。create or ...
  • weixin_41660188
  • weixin_41660188
  • 2018年01月21日 22:06
  • 37

游标的概念和作用

游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。游标充当指针的作用。尽管游标能遍历结果中的所有行,但他一次只指向一行。概括来讲,SQL的游标是一种临时的数据库对象,即可以用来存放...
  • chenjie19891104
  • chenjie19891104
  • 2009年08月08日 10:18
  • 47890

我写的第一个带游标的oracle存储过程

自己刚毕业半年,水平低下,最近几天由于工作需要,要求写个删除垃圾数据的存储过程,可我之前哪儿接触过这玩意儿啊。于是硬着头皮找资料,网上的资料狂多,可都不切实际,并没有给自己带来多大的帮助,后来看看公司...
  • sainery
  • sainery
  • 2008年02月01日 10:17
  • 1541

使用游标的触发器

-- =============================================-- Author:  吴会然-- Create date: 2008-05-22-- Descript...
  • wuhuiran
  • wuhuiran
  • 2008年06月06日 14:37
  • 909

sql 游标的基本用法

1. 定义游标定义游标语句的核心是定义了一个游标标识名,并把游标标识名和一个查询语句关联起来。DECLARE语句用于声明游标,它通过SELECT查询定义游标存储的数据集合。语句格式为:DECLARE ...
  • jack15850798154
  • jack15850798154
  • 2010年03月01日 11:14
  • 5046
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于mysql写触发器中运用游标的问题。
举报原因:
原因补充:

(最多只允许输入30个字)