zoukankan      html  css  js  c++  java
  • 存储过程

    存储过程

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

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

    处理多表多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';
  • 相关阅读:
    Hdu 5396 Expression (区间Dp)
    Lightoj 1174
    codeforces 570 D. Tree Requests (dfs)
    codeforces 570 E. Pig and Palindromes (DP)
    Hdu 5385 The path
    Hdu 5384 Danganronpa (AC自动机模板)
    Hdu 5372 Segment Game (树状数组)
    Hdu 5379 Mahjong tree (dfs + 组合数)
    Hdu 5371 Hotaru's problem (manacher+枚举)
    Face The Right Way---hdu3276(开关问题)
  • 原文地址:https://www.cnblogs.com/hereisdavid/p/13537615.html
Copyright © 2011-2022 走看看