前言
实际开发的业务中需要完成用户完成一个订单,对数据库多张表生成数据,比如生成出入库记录,快照商品记录,财务结算等等。。。
其实这些操作都是与数据库的交互,那么我们有没有什么办法通过传参数的形式直接与数据库进行交互,从而减少服务器的压力,减少数据库IO呢?下面就是本章要分享的存储过程?
一、什么是存储过程
存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,它存储在数据库中,一次编译后永久有效,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。在数据量特别庞大的情况下利用存储过程能达到倍速的效率提升。
二、为什么使用存储过程
1.处理比较复杂的业务时比较实用
2.存储过程的特点
- .存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般 SQL 语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。
- 当对数据库进行复杂操作时(如对多个表进行 Update,Insert,Query,Delete 时),可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。这些操作,如果用程序来完成,就变成了一条条的 SQL 语句,可能要多次连接数据库。而换成存储,只需要连接一次数据库就可以了。
- 存储过程可以重复使用,可减少数据库开发人员的工作量。
- 安全性高,可设定只有某此用户才具有对指定存储过程的使用权。
注意点: 来自某个大佬的劝告,mysql 的存储过程还有待实际测试。如果是正式项目,建议你用 sql server 或 oracle 的存储过程。
三、存储过程的基础语法
1.创建存储过程语法
CREATE PROCEDURE 存储过程名称 ([ 参数列表 ])
BEGIN
-- SQL语句
END ;
废话不多说直接上手操作
//首先得声明分隔符
mysql> DELIMITER //
//创建存储过程
mysql> CREATE PROCEDURE p1()
-> BEGIN
-> SELECT count(*) FROM course;
-> END
-> //
//将分隔符还原
mysql> DELIMITER ;
注意点:MySQL默认以";“为分隔符,如果我们没有声明分割符,那么编译器会把存储过程当成SQL语句进行处理,则存储过程的编译过程会报错,所以要事先用DELIMITER关键字申明当前段分隔符,这样MySQL才会将”;"当做存储过程中的代码,不会执行这些代码,用完了之后要把分隔符还原。
2. 调用存储过程
call p1();
3. 查看存储过程
SHOW CREATE PROCEDURE 存储过程名称 ; -- 查询某个存储过程的定义
4. 删除存储过程
DROP PROCEDURE [ IF EXISTS ] 存储过程名称 ;
四、变量的使用
1.declare语句
局部变量声明一定要放在存储过程体的开始
declare variable_name datetype [default value] ;
DECLARE仅被用在BEGIN … END复合语句里,并且必须在复合语句的开头,在任何其它语句之前。
2.变量赋值
SET 变量名 = 表达式值 [,variable_name = expression …]
3.用户变量
用户变量一般以@开头
五、存储过程的参数
参数有三种
- IN:该参数可以作为输入,也就是该参数需要调用方传入值
- OUT:该参数可以作为输出,也就是该参数可以作为返回值
- INOUT:该参数既可以作为输入又可以作为输出,也就是该参数既需要传入值,又可以返回值
1.in 输入参数
废话不多说,直接上例子
CREATE DEFINER=`root`@`localhost` PROCEDURE `get_student_info`(IN p_s_id INT)
begin
select * from student
WHERE s_id = p_s_id;
end
2.out输出参数
out 表示从存储过程内部传值给调用者,封装有参数的存储过程,传入学生id,返回学生名字
CREATE DEFINER=`root`@`localhost` PROCEDURE `get_student_info`(IN p_s_id INT,out out_s_name varchar(8))
begin
select s_name into out_s_name from student
WHERE s_id = p_s_id;
end
3.inout输入输出参数
inout 表示从外部传入的参数经过修改后可以返回的变量,既可以使用传入变量的值也可以修改变量的值(即使函数执行完)
CREATE DEFINER=`root`@`localhost` PROCEDURE `get_student_info`(INOUT p VARCHAR(8))
begin
select s_name into p from student
WHERE s_id = p;
end
注意这边的inout后面设置的数据类型是输出参数类型