zoukankan      html  css  js  c++  java
  • MySQL 存储过程/游标/事务

    将会用到的几个表
    mysql> DESC products;
    +------------+--------------+------+-----+---------+----------------+
    | Field      | Type         | Null | Key | Default | Extra          |
    +------------+--------------+------+-----+---------+----------------+
    | prod_id    | int(11)      | NO   | PRI | NULL    | auto_increment |
    | vend_id    | int(11)      | YES  |     | NULL    |                |
    | prod_name  | varchar(100) | YES  |     | NULL    |                |
    | prod_price | int(11)      | YES  |     | NULL    |                |
    | prod_desc  | varchar(300) | YES  |     | NULL    |                |
    +------------+--------------+------+-----+---------+----------------+
     
    mysql> DESC orders;
    +------------+-------------+------+-----+---------+----------------+
    | Field      | Type        | Null | Key | Default | Extra          |
    +------------+-------------+------+-----+---------+----------------+
    | order_num  | int(11)     | NO   | PRI | NULL    | auto_increment |
    | order_date | date        | YES  |     | NULL    |                |
    | cust_id    | varchar(20) | YES  |     | NULL    |                |
    +------------+-------------+------+-----+---------+----------------+
     
    mysql> DESC orderitems;
    +------------+-------------+------+-----+---------+----------------+
    | Field      | Type        | Null | Key | Default | Extra          |
    +------------+-------------+------+-----+---------+----------------+
    | order_num  | int(11)     | NO   | PRI | NULL    | auto_increment |
    | order_item | varchar(20) | YES  |     | NULL    |                |
    | prod_id    | varchar(20) | YES  |     | NULL    |                |
    | quantity   | int(11)     | YES  |     | NULL    |                |
    | item_price | int(11)     | YES  |     | NULL    |                |
    +------------+-------------+------+-----+---------+----------------+
     
    创建存储过程:参数需要指定 OUT / IN / INOUT
     
    CREATE PROCEDURE productpricing(
         OUT pl DECIMAL(8,2),
         OUT ph DECIMAL(8,2),
         OUT pa DECIMAL(8,2)
    )
    BEGIN
         SELECT Min( prod_price)
         INTO pl
         FROM products;
         SELECT Max( prod_price)
         INTO ph
         FROM products;
         SELECT Avg( prod_price)
         INTO pa
         FROM products;
    END;
     
    调用存储过程:
    CALL productpricing( @pricelow, @pricehigh, @priceaverage);
     
    选择返回的值:
    SELECT @pricelow;
    SELECT @pricelow,@pricehigh,@priceaverage  --选择多个
     
    删除存储过程:
    DROP PROCEDURE productpricing;
     
    -------------------------------------------------
     
    CREATE PROCEDURE ordertotal(
         INT onumber INT,
         OUT ototal DECIMAL(8,2)
    )
    BEGIN
         SELECT sum(item_price * quantity)
         FROM orderitems
         WHERE order_num = onumber
         INTO ototal;
    END;
     
    调用:
    CALL ordertotal(20005, @total);
     
    SELECT @total;
     
    存储过程实际场景:需要获得以前一样的订单合计,但需要对合计增加营业税,不过只针对某些顾客,那么需要做:
    1. 获得合计
    2. 把营业税有田间的添加到合计
    3. 返回合计(带或不带税)
     
    CREATE PROCEDURE ordertotal(
    IN onumber INT,
    IN taxable BOOLEAN,
    OUT octoal DECIMAL(8,2)
    )
    BEGIN
         -- 注释 Declare variable for total
         DECLARE total DECIMAL(8,2);
         DECLARE taxrate INT DEFAULT 6;
     
         -- Get the order total
         SELECT Sum( item_price * quantity)
         FROM orderitems
         WHERE order_num = onumber
         INTO total;
     
         -- Is this taxable ?
         IF taxable THEN
              SELECT total + (tatal / 100 *taxrate) INTO total;
         END IF;
         
         SELECT total INTO ototal;
    END;
         
    CALL ordertotal(2005, 0, @total);
    SELECT @total;
     
    检查存储过程:
    SHOW CREATE PROCEDURE ordertoal;
     
    --------------------------------------------------
    --------------------------------------------------
     
         SELECT 返回的是一个结果集,可能含有多行数据,有时候需要在检索出来的行中前进或后退一行或多行。这就是使用游标的原因。游标(CURSOR) 是一个存储在MySQL服务器上的数据库查询,它不是一条SELECT语句,而是被语句检索出来的结果集。在存储了游标之后应用程序可以根据需要滚动或浏览其中的数据。
         游标主要用于交互式应用,其中用户需要滚动屏幕上的数据,并对数据进行浏览或作出更改。
     
         MySQL游标只能用于存储过程。
    使用游标的步骤:
    1. 定义游标(针对某个SELECT语句)
    2. 打开游标
    3. 对填有数据的游标,根据需要取出各行
    4. 关闭游标
     
    简单示例:
    CREATE PROCEDURE processorders()
    BEGIN
         DECLARE ordernumbers CURSOR
         FOR
         SELECT order_num FROM orders;
     
         OPEN ordernumbers;
     
         CLOSE ordernumbers;
    END;
    ---------------- 使用游标数据
     
    CREATE PROCEDURE processorders()
    BEGIN
     
         DECLARE o INT;
         DECLARE ordernumbers CURSOR
         FOR
         SELECT order_num FROM orders;
     
         OPEN ordernumbers;
     
         FETCH ordernumbers INTO o;
     
         CLOSE ordernumbers;
    END;
    ----------------循环检索数据
     
    CREATE PROCEDURE processorders()
    BEGIN
     
         DECLARE o INT;
         DECLARE done BOOLEAN DEFAULT 0;
     
         DECLARE ordernumbers CURSOR
         FOR
         SELECT order_num FROM orders;
     
         -- Declare continue handler
         DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
         -- SQLSTATE '02000' 是一个未找到条件,当没有更多行可读的时候设置 done = 1 然后退出
     
         OPEN ordernumbers;
         REPEAT
     
              FETCH ordernumbers INTO o;
     
         UNTIL done END REPEAT;
     
         CLOSE ordernumbers;
    END;
    -----------------------------------------------------
    -----------------------------------------------------
    ------使用table 记录CURSOR FETCH 出来的值
    CREATE PROCEDURE processorders()
    BEGIN
     
         DECLARE o INT;
         DECLARE done BOOLEAN DEFAULT 0;
         DECLARE t DECIMAL(8,2);
     
         DECLARE ordernumbers CURSOR
         FOR
         SELECT order_num FROM orders;
     
         -- Declare continue handler
         DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
         -- SQLSTATE '02000' 是一个未找到条件,当没有更多行可读的时候设置 done = 1 然后退出
     
         -- 创建table
         CREATE TABLE IF NOT EXISTS ordertotals(
              order_num INT, total DECIAML(8,2)
         );
     
         OPEN ordernumbers;
         REPEAT
     
              FETCH ordernumbers INTO o;
              CALL ordertotal(o,1,t); -- 调用过程
     
              -- 插入table
              INSERT INTO ordertotals(order_num, total)
              VALUES(o,t);
     
         UNTIL done END REPEAT;
     
         CLOSE ordernumbers;
    END;
    -----------------------------------------------------
    -----------------------------------------------------
    触发器:在事件发生的时候自动执行
    创建触发器时,需要给出4条信息:
    1.唯一的触发器名
    2.触发器关联的表
    3.触发器应该响应的活动(DELETE/ INSERT / UPDATE)
    4.触发器何时执行
    --------------------
    CREATE TRIGGER newproduct AFTER INSERT ON products FOR EACH ROW SELECT 'Product added';
     
    --该例子触发器在每次插入之后显示 Product added 消息
     
    ---删除触发器
     
    DROP TRIGGER newproduct;
     
    --------------------------------------------------
    --------------------------------------------------
    事务处理( transaction processing) 可以用来维护数据库的完整性,它保证成批的MySQL操作要么完全执行,要么不执行。
    几个术语:
    事务:transaction 指一组SQL语句
    回退:rollback 指撤销指定SQL语句过程
    提交:commit 指将为存储的SQL语句结果写入数据库表
    保留点:savepoint 指事务处理中设置的临时占位符,你可以对它发布退回
    -------------
    SELECT * FROM ordertotals;
    START TRANSACTION;
    DELETE FROM ordertotals; --删除表
    SELECT * FROM ordertotals; -- 确认删除
    ROLLBACK; -- 回滚
    SELECT * FROM ordertotal; -- 再次显示
     
    --------------commit
    一般的MySQL语句都是直接针对数据库表进行操作,进行隐含的提交,即提交操作是自动执行的。
    在 事务处理中,提交不会隐含执行,需要使用COMMIT语句。
    START TRANSACTION;
    DELETE FROM orderitems WHERE order_num = 20010;
    DELETE FROM orders WHERE order_num = 20010;
    COMMIT;
  • 相关阅读:
    GDB 进行调试 使用心得
    libnet发包例子(tcp udp arp广播)
    epoll源码实现分析[整理]
    Linux中的时间和时间管理
    PHP生成压缩文件开发实例
    sql语句删除数据表重复字段的方法
    亿级Web系统搭建——单机到分布式集群
    微信开发之附近商家地理位置计算和腾讯地图坐标转百度地图坐标的方法
    PHP生成订单号(产品号+年的后2位+月+日+订单号)
    (用微信扫的静态链接二维码)微信native支付模式官方提供的demo文件中的几个bug修正
  • 原文地址:https://www.cnblogs.com/zhuyp1015/p/3575823.html
Copyright © 2011-2022 走看看