Mysql存储过程

11 篇文章 0 订阅
6 篇文章 0 订阅

简介

  • 存储过程(Stored Procedure)是封装了一些 SQL语句和控制结构的函数

优点

  1. 可以在数据库内完成较复杂的判断及运算, 且改动时无需修改项目源代码
  2. 从代码请求的 SQL语句, 每次请求都会重新进行编译, 如某一操作中有大量的 SQL语句, 可以通过存储过程实现, 因为存储过程是预编译的, 所以一次处理越多语句速度相对越快
  3. 能减少网络负载, 因为从代码请求的 SQL语句都是把整条语句通过网络传到数据库中执行, 不过存储过程是只需传相关存储过程名称和参数
  4. 可以作为一种安全机制来使用, 如对某一存储过程进行权限限制, 对特定数据的访问和改动限定指定的存储过程来操作

创建语句

  • CREATE PROCEDURE 存储过程名称([[IN|OUT|INOUT] 参数名称 数据类形…]) 存储过程体

删除语句(目前 Mysql不支持修改存储过程只能删除后再创建

  • DROP PROCEDURE 存储过程名称;

三种查询语句

  1. SHOW PROCEDURE STATUS WHERE db=‘数据库名称’;
  2. SELECT name FROM mysql.proc WHERE db=‘数据库名称’;
  3. SELECT routine_name FROM information_schema.routines WHERE routine_schema=‘数据库名称’;

参数说明

参数说明
IN参数只能传入值, 但无法返回值
OUT参数无法传入值, 但能返回值
INOUT参数可以传入值, 并且也可以返回值

参数 IN的简单例子


mysql> DELIMITER $$
mysql> CREATE PROCEDURE procedure_01(IN in_01 INT)
    -> BEGIN
    -> SELECT in_01;
    -> SET in_01=2;
    -> SELECT in_01;
    -> END;
    -> $$
Query OK, 0 rows affected

mysql> DELIMITER ;
mysql> SET @in_01=1;
Query OK, 0 rows affected

mysql> CALL procedure_01(@in_01);
+-------+
| in_01 |
+-------+
|     1 |
+-------+
1 row in set

+-------+
| in_01 |
+-------+
|     2 |
+-------+
1 row in set

Query OK, 0 rows affected

mysql> SELECT @in_01;  
+--------+
| @in_01 |
+--------+
|      1 |
+--------+
1 row in set

  • 可以看出, 在存储过程体中参数 @in_01被修改, 但并不影响外部变量 @in_01的值

参数 OUT的简单例子


mysql> DELIMITER $$
mysql> CREATE PROCEDURE procedure_02(OUT out_01 INT)
    -> BEGIN
    -> SELECT out_01;
    -> SET out_01=2;
    -> SELECT out_01;
    -> END;
    -> $$
Query OK, 0 rows affected

mysql> DELIMITER ;
mysql> SET @out_01=1;
Query OK, 0 rows affected

mysql> CALL procedure_02(@out_01);
+--------+
| out_01 |
+--------+
| NULL   |
+--------+
1 row in set

+--------+
| out_01 |
+--------+
|      2 |
+--------+
1 row in set

Query OK, 0 rows affected

mysql> SELECT @out_01; 
+---------+
| @out_01 |
+---------+
|       2 |
+---------+
1 row in set

  • 可以看出, 变量 @out_01的初始值无法传入到存储过程内部, 不过内部改动会影响外部变量 @out_01的值

参数 INOUT的简单例子


mysql> DELIMITER $$
mysql> CREATE PROCEDURE procedure_03(INOUT inout_01 INT)
    -> BEGIN
    -> SELECT inout_01;
    -> SET inout_01=2;
    -> SELECT inout_01;
    -> END;
    -> $$
Query OK, 0 rows affected

mysql> DELIMITER ;
mysql> SET @inout_01=1;
Query OK, 0 rows affected

mysql> CALL procedure_03(@inout_01);
+----------+
| inout_01 |
+----------+
|        1 |
+----------+
1 row in set

+----------+
| inout_01 |
+----------+
|        2 |
+----------+
1 row in set

Query OK, 0 rows affected

mysql> SELECT @inout_01;
+-----------+
| @inout_01 |
+-----------+
|         2 |
+-----------+
1 row in set

  • 可以看出, 变量 @inout_01的初始值传入到存储过程内部, 并且内部改动会影响外部变量 @inout_01的值

变量

全局变量

  • 初始化变量
  1. SET @var_name=‘Hello world 1’;
  2. SELECT ‘Hello world 2’ INTO @var_name;

mysql> SELECT @var_name;
+---------------+
| @var_name     |
+---------------+
| Hello world 2 |
+---------------+
1 row in set

局部变量

  • 变量类型对应 Mysql的数据类型

mysql> DELIMITER $$
CREATE PROCEDURE procedure_04()
BEGIN
DECLARE var_int INT UNSIGNED DEFAULT 0;
DECLARE var_varcahr VARCHAR(255) DEFAULT 'This is default value';
DECLARE var_cahr CHAR(9) DEFAULT NULL;
DECLARE var_datetime DATETIME DEFAULT '2019-12-19 01:01:01';
DECLARE var_smallint SMALLINT DEFAULT 10;
DECLARE var_float FLOAT(6,2) DEFAULT 0.01;
DECLARE var_double DOUBLE(4,2) DEFAULT 0.02;
DECLARE var_decimal DECIMAL(4,2) DEFAULT 0.03;
SET var_int=100;
-- SET var_varcahr='init varcahr';
-- SET var_cahr='init char';
-- SET var_datetime='2019-12-19 15:49:01';
-- SET var_smallint=20;
-- SET var_float=0.02;
SELECT CONCAT('var_int:',var_int), CONCAT('var_varcahr:',var_varcahr), CONCAT('var_cahr:',var_cahr), CONCAT('var_datetime:',var_datetime), CONCAT('var_smallint:',var_smallint), CONCAT('var_float:',var_float), CONCAT('var_double:',var_double), CONCAT('var_decimal:',var_decimal);
END;
$$
Query OK, 0 rows affected

mysql> DELIMITER ;
mysql> CALL procedure_04();
+----------------------------+------------------------------------+------------------------------+--------------------------------------+--------------------------------------+--------------------------------+----------------------------------+------------------------------------+
| CONCAT('var_int:',var_int) | CONCAT('var_varcahr:',var_varcahr) | CONCAT('var_cahr:',var_cahr) | CONCAT('var_datetime:',var_datetime) | CONCAT('var_smallint:',var_smallint) | CONCAT('var_float:',var_float) | CONCAT('var_double:',var_double) | CONCAT('var_decimal:',var_decimal) |
+----------------------------+------------------------------------+------------------------------+--------------------------------------+--------------------------------------+--------------------------------+----------------------------------+------------------------------------+
| var_int:100                | var_varcahr:This is default value  | NULL                         | var_datetime:2019-12-19 01:01:01     | var_smallint:10                      | var_float:0.01                 | var_double:0.02                  | var_decimal:0.03                   |
+----------------------------+------------------------------------+------------------------------+--------------------------------------+--------------------------------------+--------------------------------+----------------------------------+------------------------------------+
1 row in set

Query OK, 0 rows affected

控制语句

if语句

  1. if 条件语句 then true体 end if
  2. if 条件语句 then true体 else false体 end if

mysql> DELIMITER $$
CREATE PROCEDURE procedure_05(IN arg1 INT)
BEGIN
DECLARE var_varcahr VARCHAR(255) DEFAULT 'This is default value';
IF arg1 > 0 THEN  
SET var_varcahr=CONCAT('总计:',arg1);
ELSE
SET var_varcahr='空';
END IF;
SELECT var_varcahr;
END;
$$
DELIMITER ;
CALL procedure_05(0);
Query OK, 0 rows affected

+-------------+
| var_varcahr |
+-------------+
| 空          |
+-------------+
1 row in set

Query OK, 0 rows affected

mysql> CALL procedure_05(1);
+-------------+
| var_varcahr |
+-------------+
| 总计:1      |
+-------------+
1 row in set

Query OK, 0 rows affected

case语句

  • case 变量 [when 条件值 then true体]… else 默认体 end case

mysql> DELIMITER $$
CREATE PROCEDURE procedure_06(IN arg1 INT)
BEGIN
DECLARE var_varcahr VARCHAR(255) DEFAULT 'This is default value';
CASE arg1
WHEN 0 THEN 
SET var_varcahr='零';
WHEN 1 THEN 
SET var_varcahr='一';
WHEN 2 THEN 
SET var_varcahr='二';
ELSE
SET var_varcahr='其它';
END CASE;
SELECT var_varcahr;
END;
$$
DELIMITER ;
CALL procedure_06(0);
Query OK, 0 rows affected

+-------------+
| var_varcahr |
+-------------+
| 零          |
+-------------+
1 row in set

Query OK, 0 rows affected

mysql> CALL procedure_06(1);
+-------------+
| var_varcahr |
+-------------+
| 一          |
+-------------+
1 row in set

Query OK, 0 rows affected

mysql> CALL procedure_06(6);
+-------------+
| var_varcahr |
+-------------+
| 其它        |
+-------------+
1 row in set

Query OK, 0 rows affected

while循环语句

  • while 条件语句 do true体 end while

mysql> DELIMITER $$
CREATE PROCEDURE procedure_07(IN arg1 INT)
BEGIN
WHILE arg1 <= 1 DO 
SET arg1=arg1+1;
SELECT arg1;
END WHILE;
SELECT CONCAT('结束:', arg1);
END;
$$
DELIMITER ;
CALL procedure_07(0);
Query OK, 0 rows affected

+------+
| arg1 |
+------+
|    1 |
+------+
1 row in set

+------+
| arg1 |
+------+
|    2 |
+------+
1 row in set

+-----------------------+
| CONCAT('结束:', arg1) |
+-----------------------+
| 结束:2                |
+-----------------------+
1 row in set

Query OK, 0 rows affected

repeat循环语句(与 while类似, 但不同在于, 首次循环是无条件的执行 true体

  • repeat true体 until 条件语句 end repeat

mysql> DELIMITER $$
CREATE PROCEDURE procedure_08(IN arg1 INT)
BEGIN
REPEAT 
SET arg1=arg1+1;
SELECT arg1;
UNTIL arg1 <= 1
END REPEAT;
SELECT CONCAT('结束:', arg1);
END;
$$
DELIMITER ;
CALL procedure_08(0);
Query OK, 0 rows affected

+------+
| arg1 |
+------+
|    1 |
+------+
1 row in set

+-----------------------+
| CONCAT('结束:', arg1) |
+-----------------------+
| 结束:1                |
+-----------------------+
1 row in set

Query OK, 0 rows affected

loop循环语句(与其它循环语句自身不带条件语句, 只有结束语句

  • LOOP_LABLE:loop 循环体 if 条件语句 then leave LOOP_LABLE end if end loop

mysql> DELIMITER $$
CREATE PROCEDURE procedure_09(IN arg1 INT)
BEGIN
LOOP_LABLE:LOOP 
SET arg1=arg1+1;
SELECT arg1;
IF arg1 <= 1 THEN
LEAVE LOOP_LABLE;
END IF;
END LOOP;
SELECT CONCAT('结束:', arg1);
END;
$$
DELIMITER ;
CALL procedure_09(0);
Query OK, 0 rows affected

+------+
| arg1 |
+------+
|    1 |
+------+
1 row in set

+-----------------------+
| CONCAT('结束:', arg1) |
+-----------------------+
| 结束:1                |
+-----------------------+
1 row in set

Query OK, 0 rows affected

如果您觉得有帮助,欢迎点赞哦 ~ 谢谢!!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值