存储过程

存储过程

当一个完整的操作需要多条语句才能完成,如

  • 为处理订单,需要核对以保证库存中有相应的物品
  • 如果库存里有物品,则将物品预订以边不将其卖给他人,并且要减少可用的物品数量以反映正确的库存量
  • 库存中没有的物品需要订购,与供货商进行交互
  • 关于哪些物品入库并可以立即发货的,和那些物品退订,要通知相应的客户

处理多表多MySQL语句

  • 单独编写每条语句,并根据结果有条件地执行另外的语句。在每次需要这个处理时都要重复做
  • 创建存储过程,即为之后的使用而保存的一条或多条语句的集合。可以视为批文件,但作用不仅限于批处理

存储过程的优势

  • 简单
    • 通过把处理封装在容易使用的单元中,简化复杂操作
    • 由于不要求反复建立一系列处理步骤,这保证了数据的完整性。如果所有开发人员和应用程序都使用同一(试验和测试)存储过程,则所使用的代码都是相同的。防止错误
  • 安全
    • 简化对变动的管理。如果表名、列名或业务逻辑有变化,只需要更改存储过程的代码。其他人员甚至不需要知道这些变化。安全性
  • 高性能
    • 提高性能。因为使用存储过程比使用单独的SQL语句要快
    • 存在一些只能用在单个请求中的MySQL元素和特性,存储过程 可以使用他们来编写功能更强更灵活的代码

存储过程的缺陷

  • 存储过程的编写比基本SQL语句复杂,编写存储过程需要更高技能,更丰富经验
  • 创建存储过程权限限制,未必有权限

存储过程使用

执行存储过程

调用存储过程CALL,接收存储过程名字已经所需传参 

1 CALL productpricing(@pricelow,
2             @pricehigh,
3             @priceaverage);

创建存储过程

例:返回产品平均价格的存储过程

创建存储过程: 

1 CREATE PROCEDURE productpricing()
2 BEGIN
3   SELECT Avg(prod_price) AS priceaverage
4   FROM products;
5 END
6 #存储过程名productpricing,若存储过程要接收参数,在()中列举
7 #BEGIN ENG 限定存储过程体,过程体本身只是简单的SELECT语句

当MySQL处理这段代码将创建一个新的存储过程productpricing。没有调用存储过 程,故没有返回数据。

使用存储过程:

1 CALL productpricing()

删除存储过程

1 DROP PROCEDURE productpricing;

注意删除存储过程时,没有使用后面的(),只用给出存储过程名。

仅当存在时删除:

如果指定的过程不存在,删除会报错,可以用

DROP PROCEDURE IF EXISTS productpricing;

传递参数

一般存储过程并不会显示结果,而是把结果返回给指定的变量

变量variable:用来临时存储数据

--例1、创建存储过程: 

 1 CREATE PROCEDURE productpricing(
 2 OUT pl DECIMAL(8,2),
 3 OUT ph DECIMAL(8,2),
 4 OUT pa DECIMAL(8,2)
 5 )
 6 BEGIN
 7   SELECT Min(prod_price)
 8   INTO pl
 9   FROM products;
10   SELECT Max(prod_price)
11   INTO ph
12   FROM products;
13   SELECT Avg(prod_price)
14   INTO pa
15   FROM products;
16 END;
  • 接收3个参数:pl最低价格,ph最高价格,pa平均价格
  • OUT 指出相应的参数用来从存储过程传出一个值返回给调用者
  • IN(传递给存储过程),OUT(从存储过程传出),INOUT(对存储过程传入和传出)
  • 通过指定INTO将检索结果保存到相应变量
  • 不能通过一个参数返回多个行和列

--例1、调用存储过程:

1 CALL productpricing(@pricelow,
2             @pricehigh,
3             @priceaverage);
  • 存储过程要求3个参数,则必须传参3个。
  • 所有MySQL变量都必须@开始

--例1、显示检索结果:  

1 SELECT @priceaverage;
2 ############
3 SELECT @pricelow,@pricehigh,@priceaverage;

----------------------------------------------------------------------------

--例2、创建存储过程: 

 1 # 接收订单号并返回该订单的合计
 2 CREATE PROCEDURE ordertotal(
 3 IN onumber INT,
 4 OUT ototal DECIMAL(8,2)
 5 )
 6 BEGIN
 7   SELECT Sum(item_price*quantity)
 8   FROM orderitems
 9   WHERE order_num = onumber
10   INTO ototal;
11 END;

订单号onumber定义为IN,传入存储过程

合计ototal定义为OUT,从存储过程返回合计

INTO使用otoal存储计算出来的合计

--例2、调用存储过程: 

1 CALL ordertotal(20005,@total);

--例2、显示检索结果: 

1 SELECT @total

建立智能存储过程

发挥存储过程真正的实例,在存储过程中包含业务规则和智能处理,如:

  • 获得订单的合计
  • 把营业税有条件的添加到合计
  • 返回合计
 1 ‐‐ 方法名:ordertotal
 2 ‐‐ 规则:onumber = order number
 3 ‐‐    taxable = 0 if not taxable,1 if taxable
 4 ‐‐    ototal = order total variable
 5 CREATE PROCEDURE ordertotal(
 6   IN onumber INT,
 7   IN taxable BOOLEAN,
 8   OUT ototal DECIMAL(8,2)
 9 ) COMMENT 'Obtain order total, optionally adding tax'
10 BEGIN
11   ‐‐ Declare variable for total
12   DECLARE total DECIMAL(8,2);
13   ‐‐ Declare tax percentage
14   DECLARE taxrate INT DEFAULT 6;
15 
16   ‐‐ Get the order total
17   SELECT Sum(item_price*quantity)
18   FROM orderitems
19   WHERE order_num = onumber
20   INTO total;
21 
22   ‐‐ Is this taxable?
23   IF taxable THEN
24     ‐‐ add taxrate to the total
25     SELECT total+(total/100*taxrate) INTO total;
26   END IF;
27 
28   ‐‐ And finally,save to out variable
29   SELECT total INTO ototal;
30 END;

taxable布尔值,加税为真,否则为假

存储过程体中,DECLARE定义了两个局部变量并指定变量名和数据类型

在CREATE PROCEDURE语句中包含一个comment值,即将在SHOW PROCEDURE STATUS的结果中显示

调用 

1  CALL ordertotal(20005,0,@total);
2 SELECT @total;
3 ##############
4 CALL ordertotal(20005,1,@total);
5 SELECT @total;

检查存储过程

为显示用来创建一个存储过程的CREATE语句:

1 SHOW CREATE PROCEDURE ordertotal;

为获取何时由谁创建的详细信息的存储过程列表使用:

1 SHOW PROCEDURE STATUS LIKE 'ordertotal';
原文地址:https://www.cnblogs.com/hereisdavid/p/13537615.html