mysql> CALL productpricing();
+--------------+
| priceaverage |
+--------------+
| 16.133571 |
+--------------+
1 row in set (0.30 sec)
Query OK, 0 rows affected (0.30 sec)
23.2删除存储过程
DROP PROCEDURE productpricing;//当不存在时报错
DROP PROCEDURE productpricing IF EXISTS;//仅当存在时删除,不存在时不报错
23.3使用参数
一般,存储过程并不显示结果,而是把结果返回给你指定的变量。
变量:内存中一个特定的位置,用来临时存储数据。所有MySQL变量必须以@开始。
CREATE PROCEDURE order(IN onumberINT, OUT ototal DECIMAL(8,2))
BEGIN
SELECTSum(item_price*quantity)
FROMorderitems
WHEREorder_num = onumber
INTOototal;
END;
此存储过程接受两个参数,每个参数必须指定参数类型。关键字IN指出相应参数用来传递给存储过程,OUT(从存储过程传出),INOUT(对存储过程传入和传出)。存储过程的代码位于BEGIN和END语句内。
为调用这个存储过程,可使用如下语句:
CALL ordertotal(2005,@total);
为显示此合集,如下
SELECT @total;
为得到另一个订单的合计信息,需要再次调用存储过程
CALL ordertotal(2009,@total);
SELECT @total;
23.4 建立智能存储过程
只有在存储过程内包含业务规则和智能处理时,他们的威力彩真正显现出来。
CREATE PROCEDURE ordertotal(
INonumber INT,
INtaxable BOOLEAN,
OUTototal DECIMAL(8,2)
) COMMENT 'Obtain order total, optionallyadding tax'
BEGIN
--Declare variable for total
DECLARE total DECIMAL(8,2);
--DECLARE tax percentage
DECLARE taxrate INT DEFAULT 6;
--Getthe order total
SELECT Sum(item_price*quantity)
FROM orderitems
WHERE order_num = onumber
INTO total;
--Is this taxable
IFtaxable THEN
--Yes, so add taxrate to total
SELECT total+(total/100*taxrate) INTO total;
ENDIF;
--And finally,save to out variable
SELECT total INTO ototal;
END;
这里COMMERNT关键字不是必须的,但如果给出,将在SHOW PROCEDURE STATU的结果中显示。
MySQL除了IF语句,还指出ELSEIF和ELSE子句(ELSEIF还须用THEN, ELSE不使用)
调用并显示如下结果1:如下
mysql> CALL ordertotal(20005,0,@total);
Query OK, 0 rows affected (0.05 sec)
mysql> SELECT @total;
+--------+
| @total |
+--------+
| 149.87 |
+--------+
1 row in set (0.00 sec)
调用并显示如下结果2如下
mysql> CALL ordertotal(20005,1,@total);
Query OK, 0 rows affected, 1 warning (0.00sec)
mysql> SELECT @total;
+--------+
| @total |
+--------+
| 158.86 |
+--------+
1 row in set (0.00 sec)
23.5检查存储过程
为了显示用来创建一个存储过程的CREATE语句,使用SHOW CREATE PROCEDURE语句:
SHOW CREATE PROCEDURE ordertotal;
为了获得包括何时,由谁创建等详细信息的存储过程列表,使用SHOW PROCEDURE STATUS,并且可用LIKE指定一个过滤模式,例如
SHOW PROCEDURE STATUS LIKE ‘ordertotal’;
24使用游标
有时,需要在检索出来的行中前进或后退一行或多行。这就是使用游标的原因。游标是一个存储在MySQL服务器上的数据库查询,它不是一条SELECT语句,而是被该语句检索出来的结构集。在存储了游标之后,应用程序可以根据需要滚动或浏览或更改其中的数据。
24.1使用游标
步骤:
1) 在使用有游标前,必须声明它。这个过程实际上没有检索数据,它只是ing医药使用的SELECT语句
2) 一旦声明后,必须打开游标供使用。这个过程用前面定义的SELECT语句把数据实际检索出来。
3) 对于填有数据的游标,根据需要取出各行
4) 在结束游标使用时,必须关闭游标
24.2创建游标和使用游标数据
在一个游标被打开后,可以使用FETCH语句分别访问它的每一行,FETCH指定检索什么数据,检索出来的数据存储在什么地方。它还向前移动游标中的内部行指针,使下一条FETCH语句检索下一行。
举例如下:
CREATE PROCEDURE processorders()
BEGIN
--Declarelocal variables
DECLAREdone BOOLEAN DEFAULT 0;
DECLAREo INT;
DECLAREt DECIMAL(8,2);
--Declarethe cursor
DECLAREordernumbers CURSOR
FOR
SELECTorder_num FROM orders;
--Declarecontinue handler
DECLARECONTINUE HANDLER FOR SQLSTATE ‘02000’ SET done = 1;
--Createa table to store the results
CREATETABLE IF NOT EXISTS ordertotals
(order_numINT, total DECIMAL(8,2));
--Openthe cursor
OPENordernumbers;
--Loopthrough all rows
REPEAT
--Getorder number
FETCH ordernumbers INTO o;
--Getthe total for this order
CALL ordertotal(o,1,t);
--Insertorder and total into ordertotals
INSERTINTO ordertotals(order_num,total)
VALUES(o,t);
--ENDOF LOOP