#SQL语句:先编译后执行
存储过程(Stored Procedure):一组可编程的函数,是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。
优点(为什么要用存储过程?):
1)将重复性很高的一些操作,封装到一个存储过程中,简化了对这些SQL的调用
2)批量处理:SQL+循环,减少流量
3)统一接口,确保数据的安全
缺点:
1)不同数据库,语法差别很大,移植困难,换了数据库,需要重新编写;
2)不好管理,把过多业务逻辑写在存储过程不好维护,不利于分层管理,容易混乱,一般存储过程适用于个别对性能要求较高的业务,其它的必要性不是很大;
相对于oracle数据库来说,MySQL的存储过程相对功能较弱,使用较少。
一、存储过程的创建和调用
存储过程就是具有名字的一段代码,用来完成一个特定的功能。
创建的存储过程保存在数据库的数据字典中。
1、创建存储过程语法
CREATE
[DEFINER = { user | CURRENT_USER }]
PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic ...] routine_body
proc_parameter:
[ IN | OUT | INOUT ] param_name type
characteristic:
COMMENT 'string'
| LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
routine_body:
Valid SQL routine statement
[begin_label:] BEGIN
[statement_list]
……
END [end_label]
简单点:create procedure 存储过程的名字(参数列表) begin 存储过程体(SQL语句的集合); end
注意:参数列表包含三个部分: 参数模式 参数名 参数类型 参数模式: in , out, inout . (比如: in s_name varchar(20) )
DELIMITER $$ 自定义结束符$$,替换成;;。
DEFINER 存过创建者;
案例:创建一个存储过程,删除给定学生的信息
DROP PROCEDURE IF EXISTS `proc_adder`;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_adder`(IN a int, IN b int, OUT sum int)
BEGIN
#Routine body goes here...
DECLARE c int;
if a is null then set a = 0;
end if;
if b is null then set b = 0;
end if;
set sum = a + b;
END
;;
DELIMITER ; #将语句的结束符号恢复为分号
解析:
在定义过程时,使用DELIMITER ;; 命令将语句的结束符号从分号 ; 临时改为两个;;,使得过程体中使用的分号被直接传递到服务器,而不会被客户端(如mysql)解释。
2、调用存储过程:call 存过名[(传参)];
mysql> call pro_student(22);
Query OK, 1 row affected (0.03 sec)
3、存储过程体
存储过程体包含了在过程调用时必须执行的语句,例如:dml、ddl语句,if-then-else和while-do语句、声明变量的declare语句等
过程体格式:以begin开始,以end结束(可嵌套)
BEGIN
BEGIN
BEGIN
statements;
END
END
END
注意:每个嵌套块及其中的每条语句,必须以分号结束,表示过程体结束的begin-end块(又叫做复合语句compound statement),则不需要分号。
4、为语句块贴标签
[begin_label:] BEGIN
[statement_list]
END [end_label]
例如:
label1: BEGIN
label2: BEGIN
label3: BEGIN
statements;
END label3 ;
END label2;
END label1
标签有两个作用:
1)增强代码的可读性
2)在某些语句(例如:leave和iterate语句),需要用到标签
5、删除存储过程
drop procedure 存储过程名 ;
二、存储过程的参数
存储过程可以有0个或多个参数,用于存储过程的定义。
3种参数类型:
IN 输入参数:表示调用者向过程传入值(传入值可以是字面量或变量)
OUT 输出参数:表示过程向调用者传出值(可以返回多个值)(传出值只能是变量)
INOUT 输入输出参数:既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量)
建议:
输入值使用 in 参数;
返回值使用 out 参数;
inout 参数就尽量的少用。
1、in 输入参数
mysql> delimiter $$ #将语句的结束符号从分号;临时改为两个$$(可以是自定义)
mysql> CREATE PROCEDURE pro_student(IN p_id INTEGER(11))
-> BEGIN
-> DELETE FROM student
-> WHERE id= p_id;
-> END$$
Query OK, 0 rows affected (0.01 sec)
mysql> delimiter ; #将语句的结束符号恢复为分号
mysql> call pro_student(22) ; #调用存过
2、out输出参数
案例:根据学生姓名,返回对应的年龄和学生编号
mysql> delimiter $$
mysql> CREATE PROCEDURE pro_student(in sname varchar(10),out age int,out sid int)
-> BEGIN
-> select a.age ,s.id into age,sid
-> from students s
-> inner join ages a
-> on s.age_id = a.id
-> where s.sname=sname;
-> END$$
Query OK, 0 rows affected (0.01 sec)
mysql> delimiter ; #将语句的结束符号恢复为分号
mysql> call('admin',@age,@sid) ; #调用存过
mysql> select @age,@sid ;
3、inout输入参数
mysql> delimiter $$
mysql> create procedure pro_param(inout p_inout int)
-> begin
-> set p_inout=p_inout*2;
-> end $$
mysql> delimiter ;
mysql> set @p_inout=1;
mysql> call pro_param(@p_inout);
mysql> select @p_inout;
注意:存过中的参数为局部变量、@参数名为全局变量。
三、存储过程中的控制语句1、IF语句:
DROP PROCEDURE IF EXISTS `proc_if`;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_if`(IN type int)
BEGIN
#Routine body goes here...
DECLARE c varchar(500);
IF type = 0 THEN
set c = 'param is 0';
ELSEIF type = 1 THEN
set c = 'param is 1';
ELSE
set c = 'param is others, not 0 or 1';
END IF;
select c;
END
;;
DELIMITER ;
2、CASE语句:
DROP PROCEDURE IF EXISTS `proc_case`;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_case`(IN type int)
BEGIN
#Routine body goes here...
DECLARE c varchar(500);
CASE type
WHEN 0 THEN
set c = 'param is 0';
WHEN 1 THEN
set c = 'param is 1';
ELSE
set c = 'param is others, not 0 or 1';
END CASE;
select c;
END
;;
DELIMITER ;
3、循环while语句:
DROP PROCEDURE IF EXISTS `proc_while`;
DELIMITER ;;
CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_while`(IN n int)
BEGIN
#Routine body goes here...
DECLARE i int;
DECLARE s int;
SET i = 0;
SET s = 0;
WHILE i
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?