设为首页 加入收藏

TOP

MySQL入门(三)(二)
2015-11-21 01:54:17 来源: 作者: 【 】 浏览:1
Tags:MySQL 入门
过程

检查创建存储过程的SQL语句:
SHOW CREATE PROCEDURE ordertotal;

如果想获得详细信息使用:
SHOW PROCEDURE STATUS; // 列出所有的存储过程的详细信息

可以使用 LIKE 起到过滤的作用:
SHOW PROCEDURE STATUS LIKE 'ordertotal';

七、MySQL游标

7.1 什么是游标

有时,需要在检索出来的行中前进或后退一行或多行。游标(cursor)是一个存储在MySQL服务器上的数据库查询,它不是一条 SELECT 语句,而是被该语句检索出来的结果集。在存储了游标之后,应用程序可以根据需要滚动或浏览器中的数据。

7.2 使用游标

步骤:
1) 在能够使用游标前,必须声明(定义)它,这个过程实际上没有检索数据,它只是定义要使用的 SELECT 语句。
2) 一旦声明后,必须打开游标以供使用。这个过程用前面定义的 SELECT 语句把数据实际检索出来。
3) 对于填有数据的游标,根据需要取出各行。
4)在结束游标使用时,必须关闭游标。

(1) 创建游标

-- create_cursor.sql
DELIMITER  //
CREATE  PROCEDURE  processorder( )
BEGIN
    -- Declare the cursor
    DECLARE  ordernumbers  CURSOR
    FOR
    SELECT  order_num  FROM  orders;

    -- Open the cursor
    OPEN  ordernumbers;

    -- Close the cursor
    CLOSE  ordernumbers;
END//
DELIMITER  ;

MySQL中的游标只能用于存储过程,DECLARE 语句用来定义和命名游标,这里为 ordernumbers,在存储过程处理完成后,游标就会消失,因为它局限于存储过程。该存储过程只是打开和关闭了游标,并没有使用里面的数据。CLOSE 释放游标使用的内存资源,因此在每个游标不再需要时都应该关闭。如果你不明确关闭游标,MySQL 将会在到达END语句时自动关闭它。

(2) 使用游标

-- use_cursor.sql
DELIMITER  //
CREATE  PROCEDURE  processorder( )
BEGIN
    -- Declare local variables
    DECLARE  done  BOOLEAN  DEFAULT  0;
    DECLARE  onumber INT ;
    DECLARE  t  DECIMAL(8, 2);

    -- Declare the cursor
    DECLARE  ordernumbers  CURSOR
    FOR
    SELECT  order_num  FROM  orders;
    -- Declare continue handler
    DECLARE  CONTINUE  HANDLER  FOR  SQLSTATE  '02000'  SET  done = 1;

    -- Create a table to store the results
    CREATE  TABLE  IF  NOT  EXISTS  ordertotals
        (order_num  INT, total  DECIMAL(8, 2));

    -- Open the cursor
    OPEN  ordernumbers;

    -- Loop through all rows
    REPEAT
        -- Get order number
        FETCH  ordernumbers  INTO  onumber;

        -- Get the total for this order
        CALL  ordertotal(onumber, 1, t);

        -- Insert order and total into ordertotals
        INSERT  INTO ordertotals(order_num, total)  VALUES(onumber, t);

    -- End of loop
    UNTIL  done  END  REPEAT;

    -- Close the sursor
    CLOSE  ordernumbers;

END//
DELIMITER  ;

在一个游标被打开后,可以使用 FETCH 语句分别访问它的每一行。FETCH 取出检索的数据同时它还向前移动游标中的内部行指针。该例子中的 FETCH 是在 REPEAT 内,因此它反复执行直到 done 为真(由 UNTIL done END REPEAT; 实现)。结束循环条件的语句为:
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
这条语句定义了一个 CONTINUE HANDLER,它是在条件出现时被执行的代码。这里,它指出当 SQLSTATE ‘02000’ 出现时,SET done = 1。SQLSTATE ‘02000’ 是一个未找到条件,当 REPEAT 由于没有更多的行共循环时,出现这个条件。
该存储过程,计算出每个订单号的带税的合计,并新建一个表,把这些数据插入到新建的表中。

mysql> source ./work/MySQL/use_cursor.sql;
mysql> CALL  processorder( );
mysql> SELECT * FROM ordertotals;

+――――+―――?+
| order_num | total |
+――――+―――?+
| 20005 | 158.86 |
| 20009 | 40.78 |
| 20006 | 58.30 |
| 20007 | 1060.00 |
| 20008 | 132.50 |
| 20008 | 132.50 |
+――――+―――?+

八、MySQL触发器

8.1 什么是触发器

如果你先让某些语句在事件发生时自动执行,就需要用到触发器。触发器是 MySQL 响应以下任意语句而自动执行的一条 MySQL 语句:
DELETE; INSERT; UPDATE;
其它MySQL语句不支持触发器。

8.2 创建触发器

mysql> CREATE TRIGGER newproduct AFTER INSERT ON ordertotals 
     >  FOR EACH ROW SELECT 'Product added' INTO @q;

创建触发器的语法:

CREATE
    [DEFINER = { user | CURRENT_USER }]
    TRIGGER trigger_name
    trigger_time trigger_event
    ON tbl_name FOR EACH ROW
    trigger_body

trigger_time: { BEFORE | AFTER }
trigger_event: { INSERT | UPDATE | DELETE }

注意:MySQL5.6 中的触发器不能返回结果集; 只有表支持触发器,视图和临时表都不支持。
这个触发器,在每次向表 ordertotals 插入数据时(对于每行)都会执行 SELECT ‘Product added’ INTO @q 。

8.3 删除触发器

mysql> DROP TRIGGER newproduct;

触发器不能更新或覆盖,为了修改一个触发器,必须先删除它然后重新创建。

8.4 使用触发器

(1) INSERT触发器

在 INSERT 触发器代码内,可引用一个名为 NEW 的虚拟表,访问被插入的行;
在 BEFORE INSERT 触发器中, NEW 中的值也可以被更新(允许更改将要被插入的值);
对于 AUTO_INCREMENT 列,NEW在 INSERT 之前包含0,在INSERT 之后包含新的自动生成值。

mysql> CREATE TRIGGER neworder AFTER INSERT ON orders                              
    -> FOR EACH ROW SELECT NE
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇mysql检测重复索引 下一篇MySQL入门(二)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: