个人主页:我是沐风晓月
个人简介:大家好,我是沐风晓月,双一流院校计算机专业,阿里云社区专家博主
座右铭: 先努力成长自己,再帮助更多的人 ,一起加油进步
欢迎大家:这里是CSDN,我总结知识的地方,喜欢的话请三连,有问题请私信
可以关注我的云原生社区:云原生社区
也可以关注我的英语社区:从零开始学英语
百科中超难理解的版本:
MySQL 的存储过程(Stored Procedures)是一组预先定义好的 SQL 语句集合,这些语句会经过编译并存储在数据库中,可以在需要时被调用执行。存储过程可以接受输入参数、返回输出结果,并且具有复杂的逻辑处理能力。
修正后的版本:
存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。
还是不理解的话,看这里:
存储过程,你可以理解为类似于shell脚本中的函数,只不过函数是一组shell命令的组合,而存储过程是一组SQL语句的组合。
提高性能:存储过程在数据库服务器端执行,减少了与数据库服务器之间的通信开销。相比于每次向服务器发送一个查询请求,使用存储过程可以将复杂的逻辑封装在数据库内部,并通过一次调用执行多个 SQL 语句,从而减少了网络流量和服务器资源开销,提高了执行效率。
重用性和模块化:存储过程可以在多个应用程序中重复使用,避免了重复编写相同的 SQL 语句逻辑。它们提供了一种模块化的方式来组织和管理数据库逻辑,使得开发人员可以专注于业务逻辑层面的实现,提高了开发效率。
降低代码复杂性:存储过程可以封装复杂的业务逻辑和数据操作,并暴露简单的接口供应用程序调用。这样可以将复杂性从应用程序中移除,使得应用程序的代码变得更简洁、清晰,易于维护和理解。
数据安全性:存储过程可以对用户的权限进行控制,为数据库提供了一种更强大的访问控制机制。通过存储过程,可以限制对特定数据表和数据字段的访问,确保只有授权的用户能够执行特定的操作,提升了数据库的安全性。
事务管理和数据一致性:存储过程可以嵌入事务语句,提供了对复杂操作的原子性执行和数据一致性的保证。通过使用存储过程,可以确保在一次调用中执行的所有 SQL 操作要么全部成功提交,要么全部回滚,避免了因为异常情况导致的数据不一致问题。
性能优化和查询优化:存储过程可以对复杂的查询语句进行优化,通过使用合适的索引、查询重写和查询优化技术,提高查询性能。此外,存储过程还可以缓存查询计划,避免了每次执行查询时重新生成查询计划的开销,提升了查询效率。
# 声明存储过程
create procedure 过程名(参数1,参数2....)
# 存储过程的开始符号begin ,结束符合end
begin
sql语句;
sql语句;
end
需要注意的是: 创建存储过程之前我们必须修改mysql语句默认结束符“ ; 要不然我们不能创建成功。
使用delimiter可以修改执行符号:
DELIMITER $$
或者
DELIMITER //
这里的book库是我自己的数据库。
mysql>use book;
注意: 必须先进入数据库 book
mysql> delimiter % 这样结束符就为%
mysql> create procedure selCg()
-> begin
-> select * from category;
-> end %
也可以这么写:
mysql> create procedure selCg() begin select * from category; end%
call 过程名(参数1,参数2);
调用案例:
mysql> call selCg()%
+---------+---------------+
| bTypeId | bTypeName |
+---------+---------------+
| 1 | windows应用 |
| 2 | 网站 |
| 3 | 3D动画 |
| 4 | linux学习 |
| 5 | Delphi学习 |
| 6 | 黑客 |
| 7 | 网络技术 |
| 8 | 安全 |
| 9 | 平面 |
| 10 | AutoCAD技术 |
+---------+---------------+
10 rows in set (1.25 sec)
用完记得切换回来:
mysql> delimiter ;
语法:
drop procedure sp_name;
案例:
mysql> drop procedure selCg ;
Query OK, 0 rows affected (0.13 sec
特点:读取外部变量值,且有效范围仅限存储过程内部。
use book;
mysql> delimiter //
mysql> create procedure demo1(in abc int)
-> begin
-> select abc;
-> set abc=66;
-> select abc;
-> end;
-> //
Query OK, 0 rows affected (0.43 sec)
mysql> delimiter ; 使用完马上恢复默认的
传入值进去:
mysql> call demo1(60);
+------+
| abc |
+------+
| 60 |
+------+
1 row in set (0.03 sec)
+------+
| abc |
+------+
| 66 |
+------+
1 row in set (0.04 sec
会看到传值进去后,先输入第一个select是60,在后面又重新做了赋值,是66,一共两个值。
也可以传变量进去:
mysql定义变量方法:
语法格式: set @字段名=值
例如
set @num=1
mysql> set @y=1; 局部变量
我们先来看一个变量的使用案例:
mysql> set @y=1;
Query OK, 0 rows affected (0.10 sec)
mysql> select @y
-> ;
+------+
| @y |
+------+
| 1 |
+------+
1 row in set (0.54 sec)
接下来我们传入变量到存储过程:
mysql> call demo1(@y);
+------+
| abc |
+------+
| 1 |
+------+
1 row in set (0.15 sec)
+------+
| abc |
+------+
| 66 |
+------+
实战案例:
定义一个存储过程 getOneBook,当输入某书籍 id 后,可以调出对应书籍记录
mysql>delimiter //
mysql> create procedure getOneBook2(in book int) begin select bid,bname,price from books where bId=book; end//
Query OK, 0 rows affected (0.01 sec)
mysql> call getOneBook2(3) //
+-----+-----------------------------+-------+
| bid | bname | price |
+-----+-----------------------------+-------+
| 3 | 网络程序与设计-asp | 43 |
+-----+-----------------------------+-------+
1 row in set (0.59 sec)
Query OK, 0 rows affected (0.59 sec)
特点:不读取外部变量值,在存储过程执行完毕后保留新值
mysql>
mysql> use book
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql>
mysql> delimiter //
mysql> create procedure pout(out p_out int)
-> begin
-> select p_out;
-> set p_out=2;
-> select p_out;
-> end;
-> //
Query OK, 0 rows affected (0.04 sec)
mysql> delimiter ;
mysql> set @p_out=1
-> ;
Query OK, 0 rows affected (0.00 sec)
mysql> call pout(@p_put);
+-------+
| p_out |
+-------+
| NULL |
+-------+
1 row in set (0.03 sec)
+-------+
| p_out |
+-------+
| 2 |
+-------+
1 row in set (0.03 sec)
Query OK, 0 rows affected (0.03 sec)
mysql>
总结:In传入参数,是外部将值传给存储过程来使用的,而out传出参数是为了让存储过程的执行结果回传给调用他的程序来使用的。
mysql> select @p_out;
+--------+
@p_out |
+--------+
2 |
+--------+
1 row in set (0.00 sec)
可以看到,外部的变量已经变成的存储过程中的变量值了。
特点:读取外部变量,在存储过程执行完后保留新值<类似银行存款>
INOUT类型的参数即可以接受调用者传入的参数,也可以向调用者返回数据
传进来,又传出去。
mysql>
mysql> delimiter //
mysql> create procedure pinout(inout p_inout int)
-> begin
-> select p_inout;
-> set p_inout=2;
-> select p_inout;
-> end;
-> //
Query OK, 0 rows affected (0.04 sec)
mysql> delimiter ;
mysql> set @p_inout=1
-> ;
Query OK, 0 rows affected (0.00 sec)
mysql> call pinout(@p_inout);
+---------+
| p_inout |
+---------+
| 1 |
+---------+
1 row in set (0.12 sec)
+---------+
| p_inout |
+---------+
| 2 |
+---------+
1 row in set (0.12 sec)
Query OK, 0 rows affected (0.14 sec)
mysql> select @p_inout
-> ;
+----------+
| @p_inout |
+----------+
| 2 |
+----------+
1 row in set (0.00 sec)
mysql>
如果在创建存储过程时没有指定参数类型,则需要在调用的时候指定参数值
mysql> create table t2(id int(11)); 创建表
mysql> delimiter //
mysql> create procedure t2(n1 int)
-> begin
-> set @x=0;
-> repeat set @x=@x+1; 作了循环
-> insert into t2 values(@x);
-> until @x>n1
-> end repeat;
-> end;
-> //
mysql> delimiter ;
mysql> call t2(5); 循环5次
注释:
SET @x = 0;:初始化一个变量 “@x”,将其值设置为 0。
REPEAT:进入一个循环块,用于执行重复的操作。
SET @x = @x + 1;:将变量 “@x” 的值增加 1。
INSERT INTO t2 VALUES (@x);:将当前 “@x” 的值插入表 “t2” 的 “id” 列
UNTIL @x > n1:设置循环的终止条件,如果 “@x” 的值大于 “n1”,循环结束。
END REPEAT;:循环块的结束。
CALL t2(5);:调用存储过程 “t2”,并传入参数值 5。这将执行存储过程的逻辑,并插入 1 到 5 的值到表 “t2” 中。
执行结果:
mysql> select * from t2;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
+------+
6 rows in set (0.00 sec)
行注释以 --
开头,并位于一行的开头或任何有效语句的后面。行注释可以在存储过程的代码中的任何位置使用,并且只对该行有效。
CREATE PROCEDURE my_procedure()
BEGIN
DECLARE my_variable INT; -- 声明一个变量
SET my_variable = 1; -- 设置变量的值
-- 下面是一些代码逻辑
...
END;
CREATE PROCEDURE my_procedure()
BEGIN
DECLARE my_variable INT;
SET my_variable = 1;
/*
下面是一些代码逻辑
可以写更多的注释内容
...
*/
END;
注释可以用于提供存储过程的名称、目的说明、参数列表、返回结果、注意事项等。编写明确和详细的注释可以提高代码的可读性和可维护性,并帮助其他人快速理解和使用存储过程。
以上就是本节课的全部内容,欢迎评论区留言交流。