MySQL-存储过程

x33g5p2x  于2021-09-24 转载在 Mysql  
字(3.8k)|赞(0)|评价(0)|浏览(871)

前言

MySQL 5.0 版本开始支持存储过程。

存储过程(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。

存储过程是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。

存储过程思想上很简单,就是数据库 SQL 语言层面的代码封装与重用。

优点

  • 存储过程可封装,并隐藏复杂的商业逻辑。
  • 存储过程可以回传值,并可以接受参数。
  • 存储过程无法使用 SELECT 指令来运行,因为它是子程序,与查看表,数据表或用户定义函数不同。
  • 存储过程可以用在数据检验,强制实行商业逻辑等。

缺点

  • 存储过程,往往定制化于特定的数据库上,因为支持的编程语言不同。当切换到其他厂商的数据库系统时,需要重写原有的存储过程。
  • 存储过程的性能调校与撰写,受限于各种数据库系统。

第一个例子

我们通过一个简单的例子来学习存储过程的基本语法
基本语法:

CREATE PROCEDURE produce_name(参数列表)
beign -- 表示过程体开始 --
   -- 这里就是你的业务逻辑代码了 --
end -- 表示过程体结束 --

案例:
先说几个问题,我这里用的是Navicat。Navicat中默认的语句结束符号是“;” 但是在存储过程中我们可能会有多条语句,每条语句的结束都是“;”,为了防止创建存储过程中Navicat就使用“;”作为结束符号,我们需要重新申明结束符号:

DELIMITER $$
或
DELIMITER //

tips : 当然这个符号你可以自己定义(不要太随意就行)。
来吧!看看案例:

-- 申明结束符号 --
DELIMITER $$
CREATE PROCEDURE PROC_SELECT_BOO()
BEGIN -- 开始 --
	SELECT * FROM book;
END $$ -- 结束 --
-- 在将结束符号申明回去 --
DELIMITER ;

执行之后查看左边的结构视口:

执行存储过程:

CALL PROC_SELECT_BOO;

删除存储过程:

DROP PROCEDURE PROC_SELECT_BOOK

当然我们上面的存储过程仅仅是执行了一条查询语句。
存储过程中可以有业务逻辑,那么就需要基本的流程控制。
所以我们要写出一定质量的存储过程,就需要了解存储过程中的一些基本语法。
tips:只要你学过编程,这些都很简单。
当然,让我们觉得恶心的就是,每个不同的数据库中的存储过程的语法都不一样。这也是前面说过的存储过程最大的缺点。

基本语法

变量

MySQL的变量有:全局变量,回话变量,用户变量,系统变量,局部变量。
我们这里重点研究存储过程的使用,暂时只说局部变量。
局部变量就是申明在BEGIN和END之间的变量,作用域也就是在BEGIN和END之间。
申明变量:使用DECLARE关键字

DECLARE var_name var_type [default_value]

案例:

CREATE PROCEDURE PROC_SELECT_BOOK()
BEGIN -- 开始 --
	-- 申明变量 v_bookid 并且赋默认值为1 --
	DECLARE v_bookid int default 1;
	-- 使用变量作为查询条件 --
	SELECT * FROM book where bookid = v_bookid;
END $$ -- 结束 --

给变量赋值有两种方式:
方式1:直接set

set v_bookid = 1;

方式2: 使用select into

select count(*) into v_count from book

案例:

  • 局部变量一定要放在存储过程的开头
-- 申明结束符号 --
DELIMITER $$
CREATE PROCEDURE PROC_SELECT_BOOK()
BEGIN -- 开始 --
	-- 申明变量 v_bookid 并且赋默认值为1 --
	DECLARE v_bookid int default 0;
	DECLARE v_count int;
	-- 使用set给变量赋值 --
	SET v_bookid = 1;
	-- 使用select into 给变量赋值 --
	SELECT count(*) into v_count FROM book where bookid = v_bookid;
END $$ -- 结束 --
-- 在将结束符号申明回去 --
DELIMITER ;

流程控制语句

分支语句

[1] if…then …else
语法

-- 只有if的结构 --
if 条件  then
 执的语句
end if;
--if.. else --
if 条件  then
 	if语句
else
	else语句
end if;
-- 多重分支 --
if 条件  then
 	if语句
elseif 条件  then
	语句。。。
	。。。。。
else
	else语句
end if;

案例:

DELIMITER $$
CREATE PROCEDURE PROC_DEMO()
BEGIN
	DECLARE v_num int;
	set v_num = ROUND(RAND() * 10);
	IF MOD(v_num,2)=0 THEN
		select '偶数';
	elseif MOD(v_num,3) = 0 THEN
		select '3的倍数';
	else
		select '奇数';
	end if;
END $$
DELIMITER ;

[2]CASE结构
直接上菜吧:

DELIMITER $$
CREATE PROCEDURE PROC_DEMO()
BEGIN
	DECLARE v_num int;
	set v_num = ROUND(RAND() * 10);
	CASE v_num
	when MOD(v_num,2)=0 THEN
		select '偶数';
	when MOD(v_num,3)=0 THEN
		select '3的倍数';
	else
		select '奇数';
	end case;
END $$
DELIMITER ;
循环语句

[1]while ···· end while

while 条件 do
    --循环体
endwhile
DELIMITER $$
CREATE PROCEDURE PROC_DEMO()
BEGIN
	DECLARE v_num int default 0;
	while v_num < 10 do
	insert into temp values(v_num);
	set v_num = v_num + 1;
	end while;
END $$
DELIMITER ;

[2]repeat···· end repeat

repeat
    --循环体
until 循环条件  
end repeat;
DELIMITER $$
CREATE PROCEDURE PROC_DEMO()
BEGIN
	DECLARE v_num int default 0;
	repeat
	insert into temp values(v_num);
	set v_num = v_num + 1;
	until v_num >= 10 end repeat;
END $$
DELIMITER ;

[3]loop ·····endloop

loop 循环不需要初始条件,这点和 while 循环相似,同时和 repeat 循环一样不需要结束条件, leave 语句的意义是离开循环。

DELIMITER $$
CREATE PROCEDURE PROC_DEMO()
BEGIN
	DECLARE v_num int default 0;
	LOOP_LABLE:loop 
	insert into temp values(v_num);
	set v_num = v_num + 1;
	if v_num >=10 then 
		leave LOOP_LABLE; 
	end if;
	end loop;
END $$
DELIMITER ;

存储过程的参数

MySQL存储过程的参数用在存储过程的定义,共有三种参数类型,IN,OUT,INOUT,形式如:

CREAT EPROCEDURE 存储过程名([[IN |OUT |INOUT ] 参数名 数据类形...])
  • IN 输入参数:表示调用者向过程传入值(传入值可以是字面量或变量)
  • OUT 输出参数:表示过程向调用者传出值(可以返回多个值)(传出值只能是变量)
  • INOUT 输入输出参数:既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量)

1、in 输入参数

就简单理解为java方法的参数

delimiter $$
create procedure in_param(in p_in int)
begin
	select p_in;
	set p_in=2;
	select P_in;
end $$
delimiter ;

额~~~~
调用有输入参数的存储过程就需要传入对应的参数

call in_param(100);

2、out输出参数

就简单的理解为java中方法的返回值

delimiter $$
create procedure out_param(out p_out int)
BEGIN
	select p_out;
	set p_out = 10000;
	select p_out;
end $$
delimiter ;

调用有输出参数的存储过程

-- 这里的@p_out 就是一个用户变量 --
set @p_out=1;
call out_param(@p_out);
select @p_out;

3、inout输入参数

额!!!就字面意思。既能输入,也能输出。 其实知道就好,尽量不要使用这种类型的参数

delimiter $$
create procedure inout_param(out p_inout int)
BEGIN
	select p_inout;
	set p_inout = 10000;
	select p_inout;
end $$
delimiter ;

调用

set @p_inout=1;
call inout_param(@p_inout);
select @p_inout;

相关文章