一.什么事存储过程
存储过程:是一组为了完成特定功能的SQL语句集。经编译后存放在数据库中,用户通过指定的存储过程的名字并给定参数来调用执行他。
优点:
1 通过把处理封装在容易使用的单元中,简化复杂的操作
二.存储过程(stored procedure)、存储例程(store routine)、存储函数区别
Mysql存储例程实际包含了存储过程和存储函数,它们被统称为存储例程。
其中存储过程主要完成在获取记录或插入记录或更新记录或删除记录,即完成select insert deleteupdate等的工作。而存储函数只完成查询的工作,可接受输入参数并返回一个结果。
创建mysql存储过程、存储函数
create procedure 存储过程名(参数)
存储过程体
create function 存储函数名(参数)
三.创建存储过程
CREATE PROCEDURE 存储过程名()
如下面例子:
<span style="color:#FF0000;">DELIMITER //</span>
create procedure getInfo()
begin
select *
from work<span style="color:#FF0000;">;</span>
end<span style="color:#FF0000;">//</span>
<span style="color:#FF0000;">delimiter ; </span>
尤其注意我标红的地方,可能这些地方会导致你sql存储过程创建的失败。
说下为什么要使用delimiter :
DELIMITER 就是 告诉 mysql , 把什么字符, 作为 语句结束的字符。
默认情况下, 是 分号 ;
但是存储过程里面, 有分号的。
如果不定义
DELIMITER //
那么 mysql 遇到第一个 ; 就认为语句结束了。
用上面的例子来说, 就是
CREATE PROCEDURE getInfo()
BEGIN
SELECT * from work
就结束了, 但是这样一来, 明显是语法错误的。
因此要使用
DELIMITER //
来, 告诉 MySql , 遇到 // 符号了, 才认为整个语句结束了
这样一来
CREATE PROCEDUREgetInfo()
BEGIN
SELECT * from work
END//
才认为语句结束, 然后 mysql 尝试去 编译这个存储过程。 检查语法有效性等处理。
由于前面 存储过程创建好了。
我不希望后面的语句, 还是继续用 // 结束
否则每次
select * from ... where .. //
也是很麻烦的
这种情况下, 我创建完存储过程以后, 使用
DELIMITER ;
恢复默认值, 也就是继续把 分号, 作为 语句的结束。
上面创建的存储过程是没有待任何的参数的。其实在创建存储过程时,附带上参数:共有三种参数类型,IN,OUT,INOUT,
形式如:CREATE PROCEDURE 存储过程名([[IN |OUT |INOUT] 参数名 数据类形...])
<pre name="code" class="html">IN 输入参数:表示该参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值
OUT 输出参数:该值可在存储过程内部被改变,并可返回;定义的参数只能在过程体内部赋值,表示该参数可以将某个值传递回调用他的过程(在存储过程内部,该参数初始值为 null,无论调用者是否给存储过程参数设置值
INOUT 输入输出参数:调用时指定,并且可被改变和返回
下来看看他们使用的时候的例子:
1.in ,输入参数。在存储过程中修改该参数的值不能被返回
DELIMITER //
CREATE PROCEDURE in_demo(IN p_in int)
begin
select p_in;
set p_in = 2;
select p_in;
end//
DELIMITER ;
SET @p_in= 1;
call in_demo(@p_in);
select @p_in
执行之后,我们发现,在存储过程内,p_in的值被改成了2;但是执行完存储过程在执行select @p_in,发现它的值还是1;
2.out.该值可在存储过程内部被改变,并可返回
DELIMITER //
CREATE PROCEDURE out_demo(out p_in int)
begin
select p_in;
set p_in = 2;
select p_in;
end//
DELIMITER ;
SET @p_in= 1;
call out_demo(@p_in);
select @p_in
执行完,发现在存储过程内被修改为2,执行完存储过程后,在外面执行select @p_in,它的值还是2.已经被修改。
3. inout:调用时指定,并且可被改变和返回
delimiter //
create procedure demo_inout(inout p_inout int)
begin
select p_inout;
set p_inout =2;
select p_inout;
end //
delimiter ;
set @p_inout = 1
call demo_inout(@p_inout)
发现修改后的值,执行完后,已被修改。
四.执行存储过程
call getInfo()
a)变量的申明
局部变量申明,一定要放在存储过程体的开始
DECLARE variable_name [,variable_name...] datatype [DEFAULT value];
delimiter //
create procedure de()
begin
declare l_int int default 10;
select l_int;
end//
delimiter ;
call de();
如果在这之外 select l_int 则会报错。
b)用户变量
select 'hello world ' into @x
select @x
set @p_inout = 1;
select @p_inout
六.存储过程的查询
查询某个表下的存储过程:
select name from mysql.proc where db=’数据库名’;
select name from mysql.proc where db = 'result'
查看存储过程的详细信息:
show create procedure result.de
七.存储过程的控制语句
1.条件语句 if then ...else
delimiter //
create procedure proc2(in para int)
begin
declare var int;
set var = para + 1;
if var=0
then
select 0;
end if;
if para=0 then
select 1;
end if;
end//
delimiter ;
set @i = 0;
call proc2(@i)
2.case语句
delimiter //
create procedure proc3(in pare int)
begin
declare var int ;
set var = pare;
case var
when 0 then select 0;
when 1 then select 1;
end case;
end//
delimiter ;
set @pare = 0;
call proc3(@pare);
3.循环语句 while ... do... end while
delimiter //
create procedure proc4()
begin
declare var int ;
set var = 0;
while var<5 do
select var;
set var=var+1;
end while;
end//
delimiter ;
call proc4()
八.删除存储过程
drop PROCEDURE if exists 存储过程名;
九.存储过程与函数的区别;
不同点:
1、标识符不同。函数的标识符为FUNCTION,过程为:PROCEDURE。
2、函数中有返回值,且必须返回,而过程没有返回值。
3、过程无返回值类型,不能将结果直接赋值给变量;函数有返回值类型,调用时,除在select中,必须将返回值赋给变量。
4、函数可以在select语句中直接使用,而过程不能,例如:假设已有函数fun_getAVG() 返回number类型绝对值。那么select fun_getAVG(col_a) from table 这样是可以的。
相同点:
二者都可以有出参