MySQL存储过程(格式,变量,参数,流程控制...)

存储过程

其实就是mysql语句组成的脚本,也就是数据库中保存的一系列SQL命令的集合。

可以使用变量,条件判断,流程控制等

优点
提高性能 减轻网络负担 可以防止对表的直接访问 避免重复编写SQL操作

创建过程

语法格式:

        delimiter //                                          //delimiter 关键字用来指定存储过程的分隔符,默认为'';"

        create  procedure  名称()                    若不指定,编译器会把存储过程当成SQL语句进行处理,从而执行报错

        begin

         .... 功能代码

         end

           //                                                       //结束存储过程

mysql> delimiter //                   //指定分隔符//
mysql> create procedure db9.p1()
    -> begin
    -> select count(*) from db9.user;
    -> end
    -> //
Query OK, 0 rows affected (0.02 sec)

查看存储过程 

1. mysql> show procedure status;

2. mysql> select db,name,type from mysql.proc where name="存储过程名";

mysql> select db,name,type from mysql.proc where name="p1";
+-----+------+-----------+
| db  | name | type      |
+-----+------+-----------+
| db9 | p1   | PROCEDURE |
+-----+------+-----------+
1 row in set (0.00 sec)

调用/删除存储过程

call  存储过程名();                       //存储过程无参数,()可以省略;存储过程有参数,调用时必须传给参数

mysql> call db9.p1() //               //调用存储过程  
+----------+
| count(*) |
+----------+
|       42 |
+----------+
1 row in set (0.01 sec)

Query OK, 0 rows affected (0.01 sec)
mysql> delimiter ;
mysql> call db9.p1();
+----------+
| count(*) |
+----------+
|       42 |
+----------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

drop procedure  存储过程名;

mysql> drop procedure db9.p1;
Query OK, 0 rows affected (0.00 sec)

mysql> select db,name,type from mysql.proc where name="p1";
Empty set (0.00 sec)

进阶知识

变量类型

                  名称     描述                                         格式
系统变量 会话变量 使用set命令定义全局变量的修改会影响到整个服务器,但是对会话变量的修改,只会影响到当前的会话。select  @@hostname

mysql> set session  变量名=值;

全局变量 mysql>set global  变量名=值;
       用户变量

在客户端链接到数据库服务的整个过程中都是有效的。当目前链接断开后所有用户变量失效

定义 set  @变量名=值;

输出select @变量名;

       局部变量 存储过程中的begin/end。其有效范围仅限于该语句块中,语句块执行完毕后,变量失效。用declare定义 declare 

注意:局部变量  和 参数变量 调用时,变量名前不需要加@

mysql> show session variables like "sort%";
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| sort_buffer_size | 262144 |
+------------------+--------+
1 row in set (0.00 sec)
mysql> set session sort_buffer_size=40000;
Query OK, 0 rows affected (0.00 sec)

mysql> show global variables like "%semi%";
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.00 sec)
mysql> create procedure db9.p2() begin declare x int default 9; declare y char(10); set y = "jack"; select x;select y; end//
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> call db9.p2();
+------+
| x    |
+------+
|    9 |
+------+
1 row in set (0.00 sec)

+------+
| y    |
+------+
| jack |
+------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

算数运算

+(加)     -(减)      * (乘)    /(除)     DIV(整除运算)  %(取模 也就是余数)

mysql> set @z=1+2;select @z;
Query OK, 0 rows affected (0.00 sec)

+------+
| @z   |
+------+
|    3 |
+------+
1 row in set (0.00 sec)
mysql> set @x=1;set @y=3;set @z=@x*@y;select @z;

+------+
| @z   |
+------+
|    3 |
+------+
1 row in set (0.00 sec)

mysql> set @x=3;set @y=10;set @z=@y/@x;select @z;
+-------------+
| @z          |
+-------------+
| 3.333333333 |
+-------------+
1 row in set (0.00 sec)

mysql> set @x=10 div  3;
Query OK, 0 rows affected (0.00 sec)

mysql> select @x;
+------+
| @x   |
+------+
|    3 |
+------+
1 row in set (0.00 sec)
mysql> delimiter //
mysql> create procedure db9.p3()
    -> begin
    -> declare x int;declare y int;declare z int;
    -> select count(shell) into x  from db9.user  where shell="/bin/bash";   //使用sql命令查询结果赋值(into 变量名)
    -> select count(shell) into y  from db9.user  where shell="/sbin/nologin";
    -> set z = x + y;
    -> select x , y , z;
    -> end
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> call db9.p3();
+------+------+------+
| x    | y    | z    |
+------+------+------+
|    2 |   35 |   37 |
+------+------+------+
1 row in set (0.00 sec)

参数类型

关键字 名称 描述
in 输入参数 作用是给存储过程传值,必须在调用存储过程时赋值,在存储过程中该参数的值不允许修改;默认类型是in
out 输出参数 该值可在存储过程内部被改变,可返回
inout 输入/输出 调用时指定,可被改变和返回
mysql> create procedure db9.p4( in  x char(20) ) begin select name from db9.user where name=x; 
 -> end 
 -> // 
mysql> delimiter ;
Query OK, 0 rows affected (0.00 sec)
mysql> call db9.p4("root");
+------+
| name |
+------+
| root |
+------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)
mysql> create procedure db9.p5( in shellname char(20) ,out num int) begin select count(name) into num from db9.user where  shell=shellname;select num;
    -> end //
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> call db9.p5("/bin/bash",4);                     //out和inout 参数不可以赋值
ERROR 1414 (42000): OUT or INOUT argument 2 for routine db9.p5 is not a variable or NEW pseudo-variable in BEFORE trigger
mysql> call db9.p5("/bin/bash");                       //也不可以不写或者空”null“
ERROR 1318 (42000): Incorrect number of arguments for PROCEDURE db9.p5; expected 2, got 1
mysql> select @w;
+------+
| @w   |
+------+
| NULL |
+------+
1 row in set (0.00 sec)
mysql> call db9.p5("/bin/bash",@w);                   //必须用变量占位
+------+
| num  |
+------+
|    2 |
+------+
1 row in set (0.00 sec)
mysql> delimiter //
mysql> create procedure db9.p6( inout x char(30)) 
    -> begin
    -> select name,shell from db9.user where shell=x;
    -> select count(*) into x from db9.user;
    -> select x;
    -> end
    -> //
Query OK, 0 rows affected (0.01 sec)

mysql> set @i="/bin/bash";
Query OK, 0 rows affected (0.00 sec)

mysql> call db9.p6(@i);
+------+-----------+
| name | shell     |
+------+-----------+
| root | /bin/bash |
| lisi | /bin/bash |
+------+-----------+
2 rows in set (0.00 sec)
+------+
| num  |
+------+
|    2 |
+------+
1 row in set (0.00 sec)

流程控制

条件测试
类型(数值) 用途 类型(字符类) 用途
= 等于 or and ! 逻辑或,与,非
>  >= 大于,大于等于 in...   not in.. 在..范围之内,不在..范围之内
< <= 小于,小于等于 is null   is not null  字段的值为空, 不为空
!= 不等于 like 模糊匹配
between..and.. 在..与..之间 regexp  正则匹配
       

if结构

if单分支 if双分支

if 条件测试 then

   代码..

  .. ..

end if;

if  条件测试  then

   代码1..

else 

   代码2..

end if;

mysql> create procedure db9.p22() begin if 1<=2 then select user(); end if; select * from db9.user where id=1; end//                 
//if条件不成立则只输出最后一个
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> call db9.p22();          
+----------------+
| user()         |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)

+----+------+----------+------+------+---------+---------+-----------+
| id | name | password | uid  | gid  | comment | homedir | shell     |
+----+------+----------+------+------+---------+---------+-----------+
|  1 | root | x        |    0 |    0 | root    | /root   | /bin/bash |
+----+------+----------+------+------+---------+---------+-----------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)
mysql> delimiter  //
mysql> create procedure db9.p23(in line int )
    -> begin
    -> if line < 10 then 
    -> select  name,uid from db9.user where id <= line;
    -> else 
    -> select name,uid,shell from db9.user where id >= line;
    -> end if;
    -> end 
    -> //

Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> call db9.p23(7);
+----------+------+
| name     | uid  |
+----------+------+
| root     |    0 |
| bin      |    1 |
| daemon   |    2 |
| adm      |    3 |
| lp       |    4 |
| sync     |    5 |
| shutdown |    6 |
+----------+------+
7 rows in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> call db9.p23(15);
+---------------------+-------+---------------+
| name                | uid   | shell         |
+---------------------+-------+---------------+
| dbus                |    81 | /sbin/nologin |
| polkitd             |   999 | /sbin/nologin |
              ...
| lisi                |  1000 | /bin/bash     |
| mysql               |    27 | /bin/false    |
| NULL                |  1500 | NULL          |
+---------------------+-------+---------------+
28 rows in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

循环结构

while条件式循环 loop死循环 repeat条件式循环

while 条件判断 do

  循环体

    .. ..

end while;

 反复测试,只要成立就执行序列

loop

  循环体

  .. ..

end loop;

无条件,反复执行某一段代码

repeat 

   循环体

   ..  ..

 until 条件判断

end repeat;

当条件成立时结束结束循环

mysql> delimiter //
mysql> create procedure db9.p24()
    -> begin 
    -> declare x int default 1;
    -> declare y int default 1;
    -> while x <= 3 do 
    -> select y;
    -> set x=x+1;
    -> end while;
    -> end
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> call db9.p24();
+------+
| y    |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

+------+
| y    |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

+------+
| y    |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)
mysql> create procedure db9.p25() begin  declare y int default 1; loop  select y; end loop; end//
mysql> delimiter ;
mysql> call db9.p25();       //会无限循环下去,
1 row in set (1.66 sec)

+------+
| y    |
+------+
|    1 |
+------+
1 row in set (1.66 sec)

+------+
| y    |
+------+
|    1 |
+------+
...
mysql> ^C                    //可以ctrl+c 终止

mysql> create procedure db9.p26()
    -> begin
    -> declare y int default 1;
    -> repeat 
    -> select y;
    -> set y=y+1;
    -> until y=7
    -> end repeat;
    -> end
    -> //
Query OK, 0 rows affected (0.00 sec)
mysql> call db9.p26();
+------+
| y    |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

+------+
| y    |
+------+
|    2 |
+------+
1 row in set (0.00 sec)

+------+
| y    |
+------+
|    3 |
+------+
1 row in set (0.00 sec)

+------+
| y    |
+------+
|    4 |
+------+
1 row in set (0.00 sec)

+------+
| y    |
+------+
|    5 |
+------+
1 row in set (0.00 sec)

+------+
| y    |
+------+
|    6 |
+------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)
mysql> delimiter //
mysql> create procedure db9.p27(in line int )
    -> begin
    -> if line is not null then 
    -> select * from db9.user where id=line;
    -> else select * from db9.user where id=1;
    -> end if;
    -> end
    -> //                            
//定义一个过程,当用户输入行数时,显示对应行的数据,否则,直接输出第一行

Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call db9.p27(3);
+----+--------+----------+------+------+---------+---------+---------------+
| id | name   | password | uid  | gid  | comment | homedir | shell         |
+----+--------+----------+------+------+---------+---------+---------------+
|  3 | daemon | x        |    2 |    2 | daemon  | /sbin   | /sbin/nologin |
+----+--------+----------+------+------+---------+---------+---------------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)
mysql> select @u;
+------+
| @u   |
+------+
| NULL |
+------+
1 row in set (0.00 sec)

mysql> call db9.p27(@u);             //输入空
+----+------+----------+------+------+---------+---------+-----------+
| id | name | password | uid  | gid  | comment | homedir | shell     |
+----+------+----------+------+------+---------+---------+-----------+
|  1 | root | x        |    0 |    0 | root    | /root   | /bin/bash |
+----+------+----------+------+------+---------+---------+-----------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

例:输出user表中,uid字段值为偶数的用户名和对应uid号,并且统计有多少个用户?

mysql> delimiter //
mysql> create procedure db9.p28()
    -> begin
    -> declare count  int default 0;
    -> declare juid  int;
    -> declare y int default 1;
    -> declare x int;
    -> select count(*) into x from db9.user;
    -> while y <= x do select uid into juid  from db9.user where id = y;
    -> if juid % 2 = 0 then 
    -> select name,uid from db9.user where id = y;
    -> set count = count + 1;
    -> end if;
    -> set y = y+1;
    -> end while;
    -> select count;
    -> end
    -> //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call db9.p28();
+------+------+
| name | uid  |
+------+------+
| root |    0 |
+------+------+
1 row in set (0.01 sec)

+--------+------+
| name   | uid  |
+--------+------+
| daemon |    2 |
+--------+------+
1 row in set (0.01 sec)
...
...
+------+------+
| name | uid  |
+------+------+
| NULL | 1500 |
+------+------+
1 row in set (0.01 sec)

+-------+
| count |
+-------+
|    22 |
+-------+
1 row in set (0.01 sec)

Query OK, 0 rows affected (0.01 sec)

猜你喜欢

转载自blog.csdn.net/weixin_43800781/article/details/85067372