`
chenzehe
  • 浏览: 538138 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

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 没有什么区别吧,不过光是了解到这个是根本不足以 
写出Mysql fetch 过程的,还要了解其他的更深入的知识,我们才能真正的写出好的游标使用的 proc 
edure 

       首先fetch 离不开循环语句,那么先了解一下循环吧。 我一般使用Loop while 觉得比较清楚,而且代码简单。 这里使用Loop 为例:
fetchSeqLoop:Loop
    fetch fetchSeqCursor 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

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

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

这样就可以轻松实现更多层次的循环了,不过相对oracle PL/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 自动回收

 

DROP PROCEDURE IF EXISTS `INITBNSTRENDS`;

CREATE DEFINER = `huisou`@`%` PROCEDURE `INITBNSTRENDS`()
BEGIN
		DECLARE fetchSeqOk BOOLEAN;
		DECLARE _COM_ID INT;

		DECLARE _COM_ID_CURSOR CURSOR FOR SELECT id FROM e_enterprise WHERE user_id IS NOT NULL AND status<>'-3';#企业游标

		DECLARE CONTINUE HANDLER FOR NOT FOUND SET fetchSeqOk = true;#结束标识
		SET fetchSeqOk = FALSE;

    OPEN _COM_ID_CURSOR;
    _COM_ID_CURSOR:LOOP
				IF fetchSeqOk THEN
						LEAVE _COM_ID_CURSOR;
				ELSE
						FETCH _COM_ID_CURSOR INTO _COM_ID;#把企业ID值覆给_COM_ID
						#处理资讯
						BEGIN
								DECLARE _INFO_ID INT;
								DECLARE _INFO_SHORTSUBJECT VARCHAR(255);
								DECLARE _INFO_IMGPATH VARCHAR(128);
								DECLARE _INFO_ISSUEDATE DATETIME;
								DECLARE fetchSeqOk BOOLEAN DEFAULT 'inner'; 
								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';
								DECLARE CONTINUE HANDLER FOR NOT FOUND SET fetchSeqOk = true;#结束标识
								SET fetchSeqOk = FALSE;
								OPEN _INFO_CURSOR;
								_INFO_CURSOR:LOOP
										FETCH _INFO_CURSOR INTO _INFO_ID,_INFO_SHORTSUBJECT,_INFO_IMGPATH,_INFO_ISSUEDATE;
										IF fetchSeqOk THEN
												LEAVE _INFO_CURSOR;
										ELSE
												INSERT INTO bns_trends(OBJECT_ID,OBJECT_TYPE,SUMMARY,IMG_PATH,COM_ID,VOTE_NUM,COMMEND_NUM,COMMENT_NUM,CREATE_TIME,STATUS)
												VALUES(_INFO_ID,'3',_INFO_SHORTSUBJECT,_INFO_IMGPATH,_COM_ID,0,0,0,_INFO_ISSUEDATE,'1');
										END IF;
								END LOOP;
						END;

						#处理供应
						BEGIN
								DECLARE _SALE_ID INT;
								DECLARE _SALE_TITLE VARCHAR(255);
								DECLARE _SALE_IMGPATH VARCHAR(128);
								DECLARE _SALE_ISSUEDATE DATETIME;
								DECLARE fetchSeqOk BOOLEAN DEFAULT 'inner'; 
								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';
								DECLARE CONTINUE HANDLER FOR NOT FOUND SET fetchSeqOk = true;#结束标识
								SET fetchSeqOk = FALSE;
								OPEN _SALE_CURSOR;
								_SALE_CURSOR:LOOP
										FETCH _SALE_CURSOR INTO _SALE_ID,_SALE_TITLE,_SALE_IMGPATH,_SALE_ISSUEDATE;
										IF fetchSeqOk THEN
												LEAVE _SALE_CURSOR;
										ELSE												
												INSERT INTO bns_trends(OBJECT_ID,OBJECT_TYPE,SUMMARY,IMG_PATH,COM_ID,VOTE_NUM,COMMEND_NUM,COMMENT_NUM,CREATE_TIME,STATUS)
												VALUES(_SALE_ID,'1',_SALE_TITLE,_SALE_IMGPATH,_COM_ID,0,0,0,_SALE_ISSUEDATE,'1');
										END IF;
								END LOOP;
						END;

						#处理求购
						BEGIN
								DECLARE _BUY_ID INT;
								DECLARE _BUY_TITLE VARCHAR(255);
								DECLARE _BUY_IMGPATH VARCHAR(128);
								DECLARE _BUY_ISSUEDATE DATETIME;
								DECLARE fetchSeqOk BOOLEAN DEFAULT 'inner'; 
								DECLARE _BUY_CURSOR CURSOR FOR SELECT id,title,picurl,issuedate FROM e_product_buy WHERE e_id=_COM_ID AND status<>'-3';
								DECLARE CONTINUE HANDLER FOR NOT FOUND SET fetchSeqOk = true;#结束标识
								SET fetchSeqOk = FALSE;
								OPEN _BUY_CURSOR;
								_BUY_CURSOR:LOOP
										FETCH _BUY_CURSOR INTO _BUY_ID,_BUY_TITLE,_BUY_IMGPATH,_BUY_ISSUEDATE;
										IF fetchSeqOk THEN
												LEAVE _BUY_CURSOR;
										ELSE												
												INSERT INTO bns_trends(OBJECT_ID,OBJECT_TYPE,SUMMARY,IMG_PATH,COM_ID,VOTE_NUM,COMMEND_NUM,COMMENT_NUM,CREATE_TIME,STATUS)
												VALUES(_BUY_ID,'1',_BUY_TITLE,_BUY_IMGPATH,_COM_ID,0,0,0,_BUY_ISSUEDATE,'1');
										END IF;
								END LOOP;
						END;
				END IF;
		END LOOP;
END;

 
分享到:
评论
1 楼 dy.f 2012-10-27  
写得很好,通俗易懂。
想问下“DECLARE fetchSeqOk BOOLEAN DEFAULT 'inner';”为什么默认值是'inner'?

相关推荐

    Mysql游标(循环操作)

    ### MySQL游标(循环操作) #### 一、游标简介 在MySQL中,游标是一种数据库对象,主要用于处理存储过程中的结果集。游标允许我们逐行地读取查询结果,这对于需要对每一行数据执行特定操作的情况非常有用。通过...

    mysql游标

    MySQL游标是数据库管理系统中一个重要的概念,它在处理大量数据时非常有用,尤其是在需要逐行处理查询结果的情况下。游标允许程序动态地访问和操作数据集,而不是一次性加载所有结果。在MySQL中,游标主要用于存储...

    mysql游标实现到了最后一个结束之后结束循环

    MySQL游标是数据库管理系统中用于遍历查询结果集的一种机制,尤其在处理大量数据或进行迭代操作时,游标显得尤为重要。这篇博文可能是探讨如何在MySQL中使用游标,特别是当游标执行到最后一行后如何正确地结束循环。...

    mysql游标详解

    MySQL 游标详解 MySQL 从 5.0 版本开始支持存储过程和触发器,而游标在递归树结构中非常有用。游标是 MySQL 中的一种机制,允许开发人员在存储过程和触发器中控制数据的获取和处理。 在 MySQL 中,游标是通过 ...

    详解Mysql 游标的用法及其作用

    [mysql游标的用法及作用] 例子: 当前有三张表A、B、C其中A和B是一对多关系,B和C是一对多关系,现在需要将B中A表的主键存到C中; 常规思路就是将B中查询出来然后通过一个update语句来更新C表就可以了,但是B表中有...

    mysql游标存储过程例子

    根据提供的文件信息,本文将详细解释一个MySQL存储过程的例子,其中包含了游标的使用。这个存储过程主要用于处理一批数据,涉及到日期范围内的数据处理、异常处理等。下面将逐一解析存储过程中涉及的重要知识点。 #...

    MySql游标的使用实例

    MySQL游标是数据库管理系统中的一个重要概念,主要用于在存储过程或函数中逐行处理查询结果集。游标允许程序按需一次处理一行数据,而非一次性获取所有数据,这在处理大量数据时尤其有用,因为它可以避免一次性加载...

    mysql游标嵌套[文].pdf

    MySQL 游标嵌套实践 本文档旨在介绍 MySQL 游标嵌套的概念和实践,通过对游标的嵌套使用,演示如何实现复杂的数据操作。 一、游标嵌套简介 游标(Cursor)是数据库中的一种控制结构,可以用来遍历查询结果集。...

    MySQL游标:数据库操作的精准定位器

    ### MySQL 游标详解:数据库操作的精准定位器 #### MySQL 概览 MySQL 是一个广泛应用的开源关系型数据库管理系统(RDBMS),是LAMP技术栈的重要组成部分,该技术栈包括Linux操作系统、Apache Web服务器、MySQL...

    精准掌控数据流:MySQL游标在批量更新和删除中的应用

    ### MySQL 游标在批量更新和删除中的应用详解 #### 一、MySQL 游标概述 游标(Cursor)在数据库领域中是一个重要的概念,它主要用于处理查询结果集中的每一行记录,允许开发者以逐行的方式对数据进行访问和操作。...

    MySQL游标概念与用法详解

    本文实例讲述了MySQL游标概念与用法。分享给大家供大家参考,具体如下: 1、游标的概念(Cursor) 一条sql,对应N条资源,取出资源的接口,就是游标,沿着游标,可以一次取出1行。如果开发过安卓的同学应该知道有一...

    mysql游标的原理与用法实例分析

    本文实例讲述了mysql游标的原理与用法。分享给大家供大家参考,具体如下: 本文内容: 什么是游标 创建游标 使用游标 首发日期:2018-04-18 什么是游标: 如果你前面看过mysql函数,会发现无法使用返回多行...

    seliencepuppet#mysql#20.mysql游标的创建1

    在MySQL当中的游标其实和java中的iterator迭代器这种类型类似,都是一个集合,然后通过循环遍历,游标现在是用来处理结果集的,首先要设置一个游标的结束

    Mysql的游标的定义使用及关闭深入分析

    以上就是MySQL游标的定义、使用和关闭的基本概念以及如何处理游标循环的细节。理解这些概念对于编写涉及复杂数据处理的存储过程至关重要。记住,游标虽然提供了逐行处理数据的能力,但也需要注意性能影响,因为它们...

Global site tag (gtag.js) - Google Analytics