请使用 mysql 1.5 或以上version;
测试表 level ;
create table test.level (name varchar(20));
再 insert 些数据 ;
/*
初始化
*/
drop procedure if exists useCursor //
/* 建立 存储过程 create */
CREATE PROCEDURE useCursor()
BEGIN
/* 局部变量的定义 declare */
declare tmpName varchar ( 20 ) default '' ;
declare allName varchar ( 255 ) default '' ;
declare cur1 CURSOR FOR SELECT name FROM test. level ;
/* mysql 不知道为什么用异常加入判断 ?
* 此请参考官方文档 20.2.11. 光标 光标
* 这把 游标 异常后 捕捉
* 并设置 循环使用 变量 tmpname 为 null 跳出循环。
*/
declare CONTINUE HANDLER FOR SQLSTATE ' 02000 ' SET tmpname = null ;
/* 开游标 */
OPEN cur1;
/* 游标向下走一步 */
FETCH cur1 INTO tmpName;
/* 循环体 这很明显 把游标查询出的 name 都加起并用 ; 号隔开 */
WHILE ( tmpname is not null ) DO
set tmpName = CONCAT(tmpName ,";") ;
set allName = CONCAT(allName ,tmpName) ;
/* 游标向下走一步 */
FETCH cur1 INTO tmpName;
END WHILE ;
CLOSE cur1;
select allName ;
END ; //
call useCursor() //
drop procedure if exists useCursor //
/* 建立 存储过程 create */
CREATE PROCEDURE useCursor()
BEGIN
/* 局部变量的定义 declare */
declare tmpName varchar ( 20 ) default '' ;
declare allName varchar ( 255 ) default '' ;
declare cur1 CURSOR FOR SELECT name FROM test. level ;
/* mysql 不知道为什么用异常加入判断 ?
* 此请参考官方文档 20.2.11. 光标 光标
* 这把 游标 异常后 捕捉
* 并设置 循环使用 变量 tmpname 为 null 跳出循环。
*/
declare CONTINUE HANDLER FOR SQLSTATE ' 02000 ' SET tmpname = null ;
/* 开游标 */
OPEN cur1;
/* 游标向下走一步 */
FETCH cur1 INTO tmpName;
/* 循环体 这很明显 把游标查询出的 name 都加起并用 ; 号隔开 */
WHILE ( tmpname is not null ) DO
set tmpName = CONCAT(tmpName ,";") ;
set allName = CONCAT(allName ,tmpName) ;
/* 游标向下走一步 */
FETCH cur1 INTO tmpName;
END WHILE ;
CLOSE cur1;
select allName ;
END ; //
call useCursor() //
运行结果:
mysql
>
call useCursor()
//
+ -- ------------------------------------+
| allName |
+ -- ------------------------------------+
| f1;c3;c6;c5;c2;c4;c1;f1;f3;f4;f2;f5; |
+ -- ------------------------------------+
1 row in set ( 0.00 sec)
+ -- ------------------------------------+
| allName |
+ -- ------------------------------------+
| f1;c3;c6;c5;c2;c4;c1;f1;f3;f4;f2;f5; |
+ -- ------------------------------------+
1 row in set ( 0.00 sec)
三、示例
- drop procedure if exists add_test;
- # 创建存储过程 add_test
- CREATE PROCEDURE add_test()
- BEGIN
- #定义 变量
- DECLARE a int;
- DECLARE b VARCHAR(30);
- #此变可有可无,为了给个该存储函数执行成功后给个提示,运行下便知道
- DECLARE str VARCHAR(300);
- DECLARE x int;
- #这个用于处理游标到达最后一行的情况
- DECLARE s int default 0;
- #声明游标cursor_name(cursor_name是个多行结果集)
- DECLARE cursor_name CURSOR FOR select id ,name from from_data;
- #设置一个终止标记
- DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET s=1;
- set str = "--";
- #打开游标
- OPEN cursor_name;
- #获取游标当前指针的记录,读取一行数据并传给变量a,b
- fetch cursor_name into a,b;
- #开始循环,判断是否游标已经到达了最后作为循环条件
- while s <> 1 do
- set str = concat(str,x);
- insert into to_data(id,name) values(a,b);
- #读取下一行的数据
- fetch cursor_name into a,b;
- end while;
- #关闭游标
- CLOSE cursor_name ;
- select str;
- #语句执行结束
- END;
- #调用存储函数add_test
- CALL add_test()
四、补充-关于ssh上运行
由于mysql的解释器默认情况下,delimiter是分号;。在命令行客户端中,如果有一行命令以分号结束,
那么回车后,mysql将会执行该命令,我们在此处有很多分号,这样很是不方便,这种情况下,我只需
执行如下命令:
执行delimiter //
即可把分号结束换成//结束,然后在换回
delimiter ;