• 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;
    make it simple, make it happen
  • 相关阅读:
    Spring+Hibernate集成后事务与Session的一些理解。
    对Spring的一些个人理解
    centos5.8 x86_64安装oracle10g
    C#中MessageBox用法大全(附效果图)
    解决SQL Server管理器无法连接远程数据库的问题
    【sql2000数据库】Named Pipes Provider error 40
    用SQL数据库批量插入数据简介
    DBGridEH在Delphi7中的安装方法及使用说明
    sql server中datetime字段只取年月日如20060421,默认值如何设置?getdate()得到的是包含时分秒的时间。
    获取 Windows 窗体 DataGridView 控件中选定的单元格、行和列
  • 原文地址:https://www.cnblogs.com/stevenzeng/p/5157686.html
Copyright © 2020-2023  润新知