MySQL游标

 

       Mysql从 5.0 开始支持存储过程和 trigger ,给我们喜欢用 mysql 的朋友们更喜欢 mysql 的理由了,语法 
上和PL/SQL 有差别,不过搞过编程的人都知道,语法不是问题,关键是思想,大致了解语法后,就从 
变量定义,循环,判断,游标,异常处理这个几个方面详细学习了。关于游标的用法Mysql 现在提供 
的还很特别,虽然使用起来没有PL/SQL 那么顺手,不过使用上大致上还是一样。


定义游标
declare fetchSeqCursor cursor for select seqname, value from sys_sequence; 
使用游标
open fetchSeqCursor; 
fetch数据:
fetch fetchSeqCursor into _seqname, _value; 
关闭游标:
close fetchSeqCursor; 


       不过这都是针对cursor 的操作而已,和 PL/SQL 没有什么区别吧,不过光是了解到这个是根本不足以 
写出Mysqlfetch 过程的,还要了解其他的更深入的知识,我们才能真正的写出好的游标使用的 proc 
edure 

       首先fetch 离不开循环语句,那么先了解一下循环吧。 我一般使用Loopwhile 觉得比较清楚,而且代码简单。 这里使用Loop 为例:
fetchSeqLoop:Loop
    fetch fetchSeqCursor into _seqname, _value; 
end Loop; 


现在是死循环,还没有退出的条件,那么在这里和oracle 有区别, OraclePL/SQL 的指针有个隐性变 %notfoundMysql 是通过一个 Error handler 的声明来进行判断的, 
declare continue handler for Not found (do some action); 
Mysql 里当游标遍历溢出时,会出现一个预定义的 NOT FOUNDError ,我们处理这个 Error 并定义一 continuehandler 就可以叻,关于 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

fetch fetchSeqCursor into _seqname, _value; 
if fetchSeqOk then 
    leave fetchSeqLoop; 
else     
    select _seqname, _value; 
end if; 
end Loop; 
close fetchSeqCursor; 

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

fetch fetchSeqCursor into _seqname, _value;  
if fetchSeqOk then 
  leave fetchSeqLoop; 
else
  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; 

这样就可以轻松实现更多层次的循环了,不过相对oraclePL/SQL 来说, Mysql 现在还不支持动态游 
标的定义,所以很强大的动态拼出SQL 的在游标里还不能做到,不过这完全不影响我对 Mysql 的喜爱程 
度,她就想那羞涩的荷花一样,虽然没有灿烂的色彩,但那简约的色调,清新而不染一丝铅尘的高雅 
,一样吸引着无数的mysql 迷么,正如接天莲叶无穷碧,映日荷花别样红。 

 

Mysql 也有类似 Oracle 里的 execute immediate 的动态 SQL 的功能,通过这个功能可有多少弥补一 
些动态游标的缺憾叻 
set @sqlStr='select * from table where condition1 = ?'; 
prepare s1 for @sqlStr; 
execute s1 using @condition1; 如果有多个参数用逗号分隔 
deallocate prepare s1; 手工释放,或者是 connection 关闭时, server 自动回收

 

Sql代码 复制代码  收藏代码
  1. DROP PROCEDURE IF EXISTS `INITBNSTRENDS`;   
  2.   
  3. CREATE DEFINER = `huisou`@`%` PROCEDURE `INITBNSTRENDS`()   
  4. BEGIN  
  5.         DECLARE fetchSeqOk BOOLEAN;   
  6.         DECLARE _COM_ID INT;   
  7.   
  8.         DECLARE _COM_ID_CURSOR CURSOR FOR SELECT id FROM e_enterprise WHERE user_id IS NOT NULL AND status<>'-3';#企业游标   
  9.   
  10.         DECLARE CONTINUE HANDLER FOR NOT FOUND SET fetchSeqOk = true;#结束标识   
  11.         SET fetchSeqOk = FALSE;   
  12.   
  13.     OPEN _COM_ID_CURSOR;   
  14.     _COM_ID_CURSOR:LOOP   
  15.                 IF fetchSeqOk THEN  
  16.                         LEAVE _COM_ID_CURSOR;   
  17.                 ELSE  
  18.                         FETCH _COM_ID_CURSOR INTO _COM_ID;#把企业ID值覆给_COM_ID   
  19.                         #处理资讯   
  20.                         BEGIN  
  21.                                 DECLARE _INFO_ID INT;   
  22.                                 DECLARE _INFO_SHORTSUBJECT VARCHAR(255);   
  23.                                 DECLARE _INFO_IMGPATH VARCHAR(128);   
  24.                                 DECLARE _INFO_ISSUEDATE DATETIME;   
  25.                                 DECLARE fetchSeqOk BOOLEAN DEFAULT 'inner';    
  26.                                 DECLARE _INFO_CURSOR CURSOR FOR SELECT id,shortsubject,micropic,issuedate FROM hc_info WHERE issue_id=_COM_ID AND issuedate>'2012-01-01' AND status<>'-3';   
  27.                                 DECLARE CONTINUE HANDLER FOR NOT FOUND SET fetchSeqOk = true;#结束标识   
  28.                                 SET fetchSeqOk = FALSE;   
  29.                                 OPEN _INFO_CURSOR;   
  30.                                 _INFO_CURSOR:LOOP   
  31.                                         FETCH _INFO_CURSOR INTO _INFO_ID,_INFO_SHORTSUBJECT,_INFO_IMGPATH,_INFO_ISSUEDATE;   
  32.                                         IF fetchSeqOk THEN  
  33.                                                 LEAVE _INFO_CURSOR;   
  34.                                         ELSE  
  35.                                                 INSERT INTO bns_trends(OBJECT_ID,OBJECT_TYPE,SUMMARY,IMG_PATH,COM_ID,VOTE_NUM,COMMEND_NUM,COMMENT_NUM,CREATE_TIME,STATUS)   
  36.                                                 VALUES(_INFO_ID,'3',_INFO_SHORTSUBJECT,_INFO_IMGPATH,_COM_ID,0,0,0,_INFO_ISSUEDATE,'1');   
  37.                                         END IF;   
  38.                                 END LOOP;   
  39.                         END;   
  40.   
  41.                         #处理供应   
  42.                         BEGIN  
  43.                                 DECLARE _SALE_ID INT;   
  44.                                 DECLARE _SALE_TITLE VARCHAR(255);   
  45.                                 DECLARE _SALE_IMGPATH VARCHAR(128);   
  46.                                 DECLARE _SALE_ISSUEDATE DATETIME;   
  47.                                 DECLARE fetchSeqOk BOOLEAN DEFAULT 'inner';    
  48.                                 DECLARE _SALE_CURSOR CURSOR FOR SELECT id,title,picurl,issuedate FROM e_product_sale WHERE e_id=_COM_ID AND issuedate>'2012-01-01' AND status<>'-3';   
  49.                                 DECLARE CONTINUE HANDLER FOR NOT FOUND SET fetchSeqOk = true;#结束标识   
  50.                                 SET fetchSeqOk = FALSE;   
  51.                                 OPEN _SALE_CURSOR;   
  52.                                 _SALE_CURSOR:LOOP   
  53.                                         FETCH _SALE_CURSOR INTO _SALE_ID,_SALE_TITLE,_SALE_IMGPATH,_SALE_ISSUEDATE;   
  54.                                         IF fetchSeqOk THEN  
  55.                                                 LEAVE _SALE_CURSOR;   
  56.                                         ELSE                                                   
  57.                                                 INSERT INTO bns_trends(OBJECT_ID,OBJECT_TYPE,SUMMARY,IMG_PATH,COM_ID,VOTE_NUM,COMMEND_NUM,COMMENT_NUM,CREATE_TIME,STATUS)   
  58.                                                 VALUES(_SALE_ID,'1',_SALE_TITLE,_SALE_IMGPATH,_COM_ID,0,0,0,_SALE_ISSUEDATE,'1');   
  59.                                         END IF;   
  60.                                 END LOOP;   
  61.                         END;   
  62.   
  63.                         #处理求购   
  64.                         BEGIN  
  65.                                 DECLARE _BUY_ID INT;   
  66.                                 DECLARE _BUY_TITLE VARCHAR(255);   
  67.                                 DECLARE _BUY_IMGPATH VARCHAR(128);   
  68.                                 DECLARE _BUY_ISSUEDATE DATETIME;   
  69.                                 DECLARE fetchSeqOk BOOLEAN DEFAULT 'inner';    
  70.                                 DECLARE _BUY_CURSOR CURSOR FOR SELECT id,title,picurl,issuedate FROM e_product_buy WHERE e_id=_COM_ID AND status<>'-3';   
  71.                                 DECLARE CONTINUE HANDLER FOR NOT FOUND SET fetchSeqOk = true;#结束标识   
  72.                                 SET fetchSeqOk = FALSE;   
  73.                                 OPEN _BUY_CURSOR;   
  74.                                 _BUY_CURSOR:LOOP   
  75.                                         FETCH _BUY_CURSOR INTO _BUY_ID,_BUY_TITLE,_BUY_IMGPATH,_BUY_ISSUEDATE;   
  76.                                         IF fetchSeqOk THEN  
  77.                                                 LEAVE _BUY_CURSOR;   
  78.                                         ELSE                                                   
  79.                                                 INSERT INTO bns_trends(OBJECT_ID,OBJECT_TYPE,SUMMARY,IMG_PATH,COM_ID,VOTE_NUM,COMMEND_NUM,COMMENT_NUM,CREATE_TIME,STATUS)   
  80.                                                 VALUES(_BUY_ID,'1',_BUY_TITLE,_BUY_IMGPATH,_COM_ID,0,0,0,_BUY_ISSUEDATE,'1');   
  81.                                         END IF;   
  82.                                 END LOOP;   
  83.                         END;   
  84.                 END IF;   
  85.         END LOOP;   
  86. END;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值