MySQL 存储过程中,使用游标查询,返回的是结果集时,如何查看调用存储过程输出结果呢?
成都创新互联公司是一家专注于成都网站建设、成都做网站与策划设计,贺州网站建设哪家好?成都创新互联公司做网站,专注于网站建设10多年,网设计领域的专业建站公司;建站业务涵盖:贺州等地区。贺州做网站价格咨询:18982081108
解决方案:存储过程不返回数据,但它能创建和填充另一个表。所以在存储过程运行中创建临时表。该临时表将保存存储过程中生成的结果集,在遍历游标时,用insert保存每条数据到临时表中。后续调用时可以用select语句查询临时表中的存储过程运行结果。
以下有 三种方式 使用游标创建一个存储过程,统计某一部门下的员工信息
方法一:Loop循环
调用存储过程:
方法二:While 循环
调用存储过程:
方法三:REPEAT 循环
调用存储过程:
上述三种实现方法在测试过程中遇到下述问题。
调用存储过程查询临时表输出结果时,会发现多循环了一次,像这样:
解决方法:
在遍历游标查询结果时,先判断游标的结束标志(done) 是否是为1,如果不是1,则向临时表中插入数据。
游标一般与循环一起使用,可以设置一个循环结束条件来跳出循环并关闭游标。
下面是一个 MySQL 的 游标处理的 例子代码。 你参考参考看看。
mysql DELIMITER //
mysql CREATE PROCEDURE TestCursor()
- BEGIN
-
- DECLARE v_id INT;
- DECLARE v_value VARCHAR(10);
-
- -- 游标控制的标志
- DECLARE no_more_departments INT;
-
- -- 定义游标.
- DECLARE c_test_main CURSOR
- FOR
- SELECT id, value FROM test_main;
-
- -- 当游标没有数据的时候
- -- 设置 no_more_departments = 1
- DECLARE CONTINUE HANDLER
- FOR
- NOT FOUND SET no_more_departments=1;
-
- -- 设置初始标志位,认为游标是有数据的.
- SET no_more_departments=0;
-
- -- 打开游标
- OPEN c_test_main;
-
- -- 获取游标数据
- FETCH c_test_main INTO v_id, v_value;
-
- -- 循环所有的行
- WHILE no_more_departments = 0 DO
- -- 输出调试信息
- SELECT v_id, v_value;
-
- -- 获取游标数据
- FETCH c_test_main INTO v_id, v_value;
- END WHILE;
-
- -- 关闭游标
- CLOSE c_test_main;
- END//
Query OK, 0 rows affected (0.00 sec)
比较基础的
可以用在存储过程的SQL语句主要有以下类型:
1、
无返回结果语句,如:INSERT,UPDATE,DROP,
DELETE等
2、
select语句返回单行变量并可传给本地变量(select
..into)
3、
返回多行结果集的select语句,并可使用游标循环处理
注意,存储过程返回的多行结果集,可以被客户端程序(如php)所接收,但要在一个存储过程中接收另一个存储过程的结果集是不可能的,一般解决办法是存入临时表供其它过程共用
4、
prepare语句
以下主要讲述游标及prepare部分
游标
定义
DECLARE
cursor_name
CURSOR
FOR
SELECT_statement;
游标操作
OPEN
打开游标
OPEN
cursor_name;
FETCH
获取游标当前指针的记录,并传给指定变量列表,注意变量数必须与游标返回的字段数一致,要获得多行数据,使用循环语句去执行FETCH
FETCH
cursor_name
INTO
variable
list;
CLOSE关闭游标
CLOSE
cursor_name
;
注意:mysql的游标是向前只读的,也就是说,你只能顺序地从开始往后读取结果集,不能从后往前,也不能直接跳到中间的记录.
一个完整的例子:
--
定义本地变量
DECLARE
o
varchar(128);
--
定义游标
DECLARE
ordernumbers
CURSOR
FOR
SELECT
callee_name
FROM
account_tbl
where
acct_timeduration=10800;
DECLARE
CONTINUE
HANDLER
FOR
NOT
FOUND
SET
no_more_departments=1;
SET
no_more_departments=0;
--
打开游标
OPEN
ordernumbers;
--
循环所有的行
REPEAT
--
Get
order
number
FETCH
ordernumbers
INTO
o;
update
account
set
allMoney=allMoney+72,lastMonthConsume=lastMonthConsume-72
where
NumTg=@o;
--
循环结束
UNTIL
no_more_departments
END
REPEAT;
--
关闭游标
CLOSE
ordernumbers;
不知道你 什么版本的 mysql
1、
我使用的 mysql, 好像没有 create or replace procedure 这样的语法。
只能 create procedure
可能是我的 mysql 版本太低了吧...
2、
MySQL 存储过程名字后面的“()”是必须的,即使没有一个参数,也需要“()”
这个不知道是不是也是我mysql 版本太低的问题。
create or replace procedure proc_updateDist
修改为
create procedure proc_updateDist ()
3、游标部分, 缺少了 DECLARE CONTINUE HANDLER
以及 判断什么时候退出循环的语句。