暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL常用函数、存储过程、光标、流程控制

陌淮缘 2017-09-25
368

1.常见函数的使用

    #创建薪水表

    CREATE TABLE salary (userid INT,salary DECIMAL(12,2));

    DESCRIBE salary;  

    #插入数据

    INSERT INTO salary VALUES(1,1000),(2,2000), (3,3000),(4,4000),(5,5000), (6,NULL) ;

    #查询  If的常见使用

    SELECT * FROM salary;  

    SELECT userid 用户ID,IF(salary>2000,'high','low') AS 工资水平 FROM salary;

    SELECT userid 用户ID,IFNULL(salary,0) AS 工资 FROM salary;

    SELECT userid 用户ID,CASE WHEN salary>2000 THEN 'high' ELSE 'low' END AS 工资水平 FROM salary;

    SELECT userid 用户ID,CASE salary WHEN 1000 THEN 'low' WHEN 2000 THEN 'mid' ELSE 'high' END AS 工资水平 FROM salary;

    #常用函数

    SELECT DATABASE();

    SELECT VERSION();

    SELECT USER();

    SELECT INET_ATON('192.168.10.177');

    SELECT INET_NTOA(INET_ATON('192.168.10.177'));

    /*1.返回字符串的加密形式*/

    SELECT PASSWORD('123456');

    /*2.返回字符串的MD5加密形式*/

    SELECT MD5('123456');

2.存储过程:

          存储过程和函数是事先经过编译并存储在数据库中的一段 SQL 语句的集合,调用存储过程和函数可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是有好处的。

     存储过程和函数的区别:

          存储过程和函数的区别在于函数必须有返回值,而存储过程没有,存储过程的参数可以使用IN、OUT、INOUT 类型,而函数的参数只能是 IN 类型的。如果有函数从其他类型的数据库迁移到 MySQL,那么就可能因此需要将函数改造成存储过程。

      DELIMITER $$

          在执行创建过程和函数之前,都会通过“DELIMITER $$”命令将语句的结束符从“;”

    修改成其他符号,这里使用的是“$$”,这样在过程和函数中的“;”就不会被 MySQL 解释

    成语句的结束而提示错误。在存储过程或者函数创建完毕,通过“DELIMITER ;”命令再将结束符改回成“;”。

      注意:

        存储过程和函数的 CREATE 语法不支持使用 CREATE ORREPLACE 对存储过程和函数进行修改,如果需要对已有的存储过程或者函数进行修改,需要执行 ALTER 语法。

       characteristic 特征值的部分进行简单的说明。

      LANGUAGE SQL:说明下面过程的 BODY 是使用 SQL 语言编写,这条是系统默认的,

    为今后 MySQL 会支持的除 SQL 外的其他语言支持的存储过程而准备。

      [NOT] DETERMINISTIC:DETERMINISTIC 确定的,即每次输入一样输出也一样的程序,

    NOT DETERMINISTIC 非确定的,默认是非确定的。当前,这个特征值还没有被优化

    程序使用。

      { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }:这些特征值提供

    子程序使用数据的内在信息,这些特征值目前只是提供给服务器,并没有根据这些

    特征值来约束过程实际使用数据的情况。CONTAINS SQL 表示子程序不包含读或写

    数据的语句。NO SQL 表示子程序不包含 SQL 语句。READS SQL DATA 表示子程序包

    含读数据的语句,但不包含写数据的语句。MODIFIES SQL DATA 表示子程序包含写

    数据的语句。如果这些特征没有明确给定,默认使用的值是 CONTAINS SQL。

      SQL SECURITY { DEFINER | INVOKER }:可以用来指定子程序该用创建子程序者的许

    可来执行,还是使用调用者的许可来执行。默认值是 DEFINER。

      COMMENT 'string':存储过程或者函数的注释信息。

    #创建测试表

    CREATE TABLE `test`(

      `id` INT(4) NOT NULL,

      `name` VARCHAR(20) NOT NULL

    );

    #查看表的描述

    DESC test;

    #插入测试数据

    INSERT INTO test VALUES(1,'admin');

    #创建存储过程向test表中插入多条语句

    /*创建存储过程 创建存储过程时不能使用IF NOT EXISTS*/

    DELIMITER $$

    CREATE PROCEDURE test_insert()

    BEGIN

        DECLARE t_error INT(4) DEFAULT 0;

        DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=1;

        START TRANSACTION;

            INSERT INTO test VALUES(4,'King');

            INSERT INTO test VALUES(NULL,'Tom');

        IF t_error=1 THEN

          ROLLBACK;

        ELSE

          COMMIT;

        END IF;

    END;$$

    #调用存储过程

    CALL test_insert;

    #1.创建存储过程

    DELIMITER $$

       CREATE PROCEDURE salary_select(IN nsalary DECIMAL,OUT found_count INT)

     READS SQL DATA

     BEGIN

     SELECT * FROM salary WHERE salary = nsalary;

     SELECT FOUND_ROWS() INTO found_count;

       END$$

    #2.调用存储过程

    CALL salary_select(2000,@a);

    SELECT @a;

    #3.删除存储过程

    DROP PROCEDURE test_select;

    DROP PROCEDURE salary_select;

    #4.查看存储过程或函数

    4.1 查看存储过程或者函数的状态

    show procedure status like 'test_insert'\G

    4.2 查看存储过程或者函数的定义

     show create procedure 'test_insert' \G

    4.3 通过查看 information_schema. Routines 了解存储过程和函数的信息

    select * from routines where ROUTINE_NAME = 'test_insert' \G

    #5.条件的定义与处理

    条件的定义和处理可以用来定义在处理过程中遇到问题时相应的处理步骤,如果没有进行条件的处理,那么在发生错误时可能会抛出异常并退出,如果对条件进行了处理,那么就不会再抛出异常。

    条件的定义:DECLARE condition_name CONDITION FOR condition_value

    条件的处理:DECLARE handler_type HANDLER FOR condition_value[,...] sp_statement

    handler_type 现在还只支持 CONTINUE 和 EXIT 两种,CONTINUE 表示继续执行下面的语句,EXIT 则表示执行终止,UNDO 现在还不支持。

    condition_value 的值可以是通过 DECLARE 定义的 condition_name,可以是 SQLSTATE 的值或者 mysql-error-code 的值或者 SQLWARNING、NOT FOUND、SQLEXCEPTION,这 3 个值是 3 种定义好的错误类别,分别代表不同的含义。

    ·SQLWARNING 是对所有以 01 开头的 SQLSTATE 代码的速记。

    ·NOT FOUND 是对所有以 02 开头的 SQLSTATE 代码的速记。

    ·SQLEXCEPTION 是对所有没有被 SQLWARNING 或 NOT FOUND 捕获的 SQLSTATE 代码的速记。

3.光标

    在存储过程和函数中可以使用光标对结果集进行循环的处理。光标的使用包括光标的声明、OPEN、FETCH 和 CLOSE,其语法分别如下。

    3.1声明光标:

    DECLARE cursor_name CURSOR FOR select_statement

    3.2OPEN 光标:

    OPEN cursor_name

    3.3FETCH 光标:

    FETCH cursor_name INTO var_name [, var_name] ...

    3.4CLOSE 光标:

    CLOSE cursor_name

    以下例子是一个简单的使用光标的过程,对 payment 表按照行进行循环的处理,按照 staff_id值的不同累加 amount 的值,判断循环结束的条件是捕获 NOT FOUND 的条件,当 FETCH 光标找不到下一条记录的时候,就会关闭光标然后退出过程。

    mysql> delimiter $$

    mysql> CREATE PROCEDURE payment_stat ()

    -> BEGIN

    -> DECLARE i_staff_id int;

    -> DECLARE d_amount decimal(5,2);

    -> DECLARE cur_payment cursor for select staff_id,amount from payment;

    -> DECLARE EXIT HANDLER FOR NOT FOUND CLOSE cur_payment;

    -> set @x1 = 0;

    -> set @x2 = 0;

    -> OPEN cur_payment;

    -> REPEAT

    -> FETCH cur_payment INTO i_staff_id, d_amount;

    -> if i_staff_id = 2 then

    -> set @x1 = @x1 + d_amount;

    -> else

    -> set @x2 = @x2 + d_amount;

    -> end if;

    -> UNTIL 0 END REPEAT;

    -> CLOSE cur_payment;

    -> END;

    -> $$

    注意:变量、条件、处理程序、光标都是通过 DECLARE 定义的,它们之间是有先后顺序的要求的。变量和条件必须在最前面声明,然后才能是光标的声明,最后才可以是处理程序的声明。

4.流程控制

    4.1IF语句

    IF 实现条件判断,满足不同的条件执行不同的语句列表,具体语法如下:

    IF search_condition THEN statement_list

    [ELSEIF search_condition THEN statement_list] ...

    [ELSE statement_list]

    END IF

    4.2CASE语句

    case  when i_staff_id = 2 then

    set @x1 = @x1 + d_amount;

    else

    set @x2 = @x2 + d_amount;

    end case;

    或者:

    case i_staff_id  when 2 then

    set @x1 = @x1 + d_amount;

    else

    set @x2 = @x2 + d_amount;

    end case;

    4.3LOOP语句

    LOOP 实现简单的循环,退出循环的条件需要使用其他的语句定义,通常可以使用 LEAVE语句实现,具体语法如下:

    [begin_label:] LOOP

    statement_list

    END LOOP [end_label]

    如果不在 statement_list 中增加退出循环的语句,那么 LOOP 语句可以用来实现简单的死循环。

    4.4LEAVE  语句

    用来从标注的流程构造中退出,通常和 BEGIN ... END 或者循环一起使用。

    mysql> CREATE PROCEDURE actor_insert ()

    -> BEGIN

    -> set @x = 0;

    -> ins: LOOP

    -> set @x = @x + 1;

    -> IF @x = 100 then

    -> leave ins;

    -> END IF;

    -> INSERT INTO actor(first_name,last_name) VALUES ('Test','201');

    -> END LOOP ins;

    -> END;

    -> $$

    4.5ITERATE  语句

    ITERATE 语句必须用在循环中,作用是跳过当前循环的剩下的语句,直接进入下一轮循环。

    mysql> CREATE PROCEDURE actor_insert ()

    -> BEGIN

    -> set @x = 0;

    -> ins: LOOP

    -> set @x = @x + 1;

    -> IF @x = 10 then

    -> leave ins;

    -> ELSEIF mod(@x,2) = 0 then

    -> ITERATE ins;

    -> END IF;

    -> INSERT INTO actor(actor_id,first_name,last_name) VALUES     (@x+200,'Test',@x);

    -> END LOOP ins;

    -> END;

    -> $$

    4.6REPEAT  语句

    有条件的循环控制语句,当满足条件的时候退出循环,案例可参照上面光标示例,具体语法如下:

    [begin_label:] REPEAT

    statement_list

    UNTIL search_condition

    END REPEAT [end_label]

    4.7WHILE  语句

    WHILE 语句实现的也是有条件的循环控制语句,即当满足条件时执行循环的内容WHILE 循环和 REPEAT 循环的区别在于:WHILE 是满足条件才执行循环,REPEAT 是满足条件退出循环;WHILE 在首次循环执行之前就判断条件,所以循环最少执行 0 次,而REPEAT 是在首次执行循环之后才判断条件,所以循环最少执行 1 次。

    mysql> delimiter $$

    mysql> CREATE PROCEDURE loop_demo ()

    -> BEGIN

    -> set @x = 1 , @x1 = 1;

    -> REPEAT

    -> set @x = @x + 1;

    -> until @x > 0 end repeat;

    -> while @x1 < 0 do

    -> set @x1 = @x1 + 1;

    -> end while;

    -> END;

    -> $$

    call loop_demo();

    从判断的条件上看,初始值都是满足退出循环的条件的,但是 REPEAT 循环仍然执行了一次以后才退出循环的,而 WHILE 循环则一次都没有执行。

    

文章转载自陌淮缘,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论