Mysql存储过程
简介
- 存储过程(Stored Procedure)是封装了一些 SQL语句和控制结构的函数
优点
- 可以在数据库内完成较复杂的判断及运算, 且改动时无需修改项目源代码
- 从代码请求的 SQL语句, 每次请求都会重新进行编译, 如某一操作中有大量的 SQL语句, 可以通过存储过程实现, 因为存储过程是预编译的, 所以一次处理越多语句速度相对越快
- 能减少网络负载, 因为从代码请求的 SQL语句都是把整条语句通过网络传到数据库中执行, 不过存储过程是只需传相关存储过程名称和参数
- 可以作为一种安全机制来使用, 如对某一存储过程进行权限限制, 对特定数据的访问和改动限定指定的存储过程来操作
创建语句
- CREATE PROCEDURE 存储过程名称([[IN|OUT|INOUT] 参数名称 数据类形…]) 存储过程体
删除语句(目前 Mysql不支持修改存储过程只能删除后再创建
- DROP PROCEDURE 存储过程名称;
三种查询语句
- SHOW PROCEDURE STATUS WHERE
db
=‘数据库名称’; - SELECT
name
FROMmysql
.proc
WHEREdb
=‘数据库名称’; - SELECT
routine_name
FROMinformation_schema
.routines
WHEREroutine_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的值
变量
全局变量
- 初始化变量
- SET @var_name=‘Hello world 1’;
- 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语句
- if 条件语句 then true体 end if
- 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
如果您觉得有帮助,欢迎点赞哦 ~ 谢谢!!
来源:CSDN
作者:Shawn Jeon
链接:https://blog.csdn.net/qcl108/article/details/103618384