(22)存储过程

一、存储过程:
是在数据库系统中,一组为了完成特定功能的sql语句集,经编译后存储在数据库中,
用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。
存储过程不仅仅是“批处理”。
存储过程是经过编译的sql语句。
二、存储过程与函数、触发器的区别?
触发器用于一些触发条件所引发的操作。触发器的执行是自动化的。
自定义函数只能通过return语句返回单个值或者表对象,而存储过程不能

三、为什么使用存储过程?
1.存储过程只在创建时进行编译,以后每次执行存储过程都不需要重新编译,而一般sql语句每执行一次就编译一次,所以使用存储过程可以提高数据库执行速度。
2.当对数据库进行复杂操作时(如对多个表进行增删改查),可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。
这些操作,如果用程序来完成,就变成了一条条的sql语句,可能要多次连接数据库,而换成存储,只需要连接一次数据库就可以
3.存储过程可以重复使用,减少数据库开发人员的工作量。
4安全性高,可设定只有某些用户才具有对指定存储过程的使用权。

四、为什么不使用存储过程?
1.可移植性差
2对于简单的sql语句,存储过程没有什么优势。
3存储过程中不一定会减少网络传输
4团队开发时需要先同意标准,否则后期维护是个麻烦。
5在大并发量访问的情况下,不宜写过多涉及运算的存储过程
6业务逻辑复杂时,特别是涉及对很大的表进行操作的时候,不如在前端先简化业务逻辑。

数据库用于互联网:尽量少些存储过程中,让数据库完成尽量简单的操作。
企业内部:可以多些存储过程,业务比较固定。

五、存储过程的参数:
①IN:读取外部变量值,且有效范围仅限存储过程内部,不会保留到外部

//创建存储过程,该存储过程需要传入一个int类型的值
delimiter //
create procedure show_user(in p_id int)
begin 
select * from t3 where id=p_id;
set p_id=3;
select * from t3 where id=p_id;
end;//

delimiter ;
set @p_id=10;
call show_user(@p_id);

②OUT:不读取外部变量值,在存储过程执行完毕后保留新值

delimiter //
create procedure show_user(out p_id int)
begin 
select * from t3 where id=p_id;
set p_id=2;
select * from t3 where id=p_id;
end;//

delimiter ;
set @p_id=10;
call show_user(@p_id);

select @p_id;//其值在存储过程中修改,在存储过程完毕后,仍然保留其值。

③INOUT:读取外部变量值,在存储过程执行完毕后保留新值

delimiter //
create procedure show_user(inout p_id int)
begin 
select * from t3 where id=p_id;
set p_id=2;
select * from t3 where id=p_id;
end;//

delimiter ;
set @p_id=10;
call show_user(@p_id);
select @p_id;

不写参数例子:
功能:向t3插入6条记录
delimiter //
create procedure t3_i(n1 int)
begin
set @x=0;
repeat set @x=@x+1;
insert into t3 values(@x,'mm',1);
until @x>n1
end repeat;
end;

delimiter ;
call t3_i(5);

变量定义和触发器相同:declare variable_name [,variable_name…] datetype [default value];
例:declare l_int int unsigned default 4000000;
变量赋值:mysql中使用set命令进行变量赋值。语法:set 变量名=表达式;
变量赋值是可以在不同的存储过程中继承的。

create procedure t3_p()
set @p_id=3//

create procedure ps()
select concat('last number was',@p_id)//

delimiter ;
call t3_p();
call ps();
select @p_id;

变量作用域:内部的变量在其作用域范围内享有更高的优先权,当执行到end,内部的变量消失,此时已经在其作用域外,
变量不再可见了。因为在存储过程外不会找到这个声明的变量,但是可以通过out,inout或者将其指派给会话变量来保存其值。

注释:单行”–” /* */ 多行

【if-then-else】
语法:
if condition then

elseif condition then

else

end if;

例子:

delimiter //
create procedure proc2(in p1 int)
begin 
declare var int;
set var=p1+1;
if var=1 then insert into t3 values(12,'ll',1);
end if;
if var=2 then insert into t3 values(12,'ll',0);
else insert into t3 values(12,'ll1',1);
end if;
end;//

【case 可以有默认值else 】
语法:
case value
when value then … –when 值1 then 结果1
when value then…
else 默认结果
end case;

delimiter //
create procedure proc3(in p1 int)
begin 
declare var int;
set var=p1+1;
case var
when 1 then insert into t3 values(13,'l3',1);
when 2 then insert into t3 values(13,'l3',0);
else insert into t3 values(13,'l33',1);
end case;
end;//

call proc3(2)//

【while 】
语法:
while condition do

end while


delimiter //
create procedure proc4(in p1 int)
begin 
declare var int;
set var=p1+1;
while (var<17) do
insert into t3 values(var,'l3',1);
set var=var+1;
end while;
end;//

call proc4(14)//

【repeat】
语法:
repeat

until condition –这里没有分号
end repeat ;

delimiter //
create procedure proc5(in p1 int)
begin 
declare var int;
set var=p1+1;
repeat 
insert into t3 values(var,'l6',1);
set var=var+1;
until var>=20 
end repeat;
end;//

call proc5(15)//

【loop】
语法:
loop

end loop

delimiter //
create procedure proc6(in p1 int)
begin 
declare var int;
set var=p1+1;
loop_lable :loop
insert into t3 values(var,'l7',1);
set var=var+1;
if var>=22 then 
leave loop_lable;
end if;
end loop loop_lable;
end;//
call proc6(20)//

【在loop中嵌套if iterate进行下次循环】

delimiter //
create procedure proc7()
begin 
declare var int default 0;
loop_lable :loop
set var=var+1;
if var<10 then iterate loop_lable;
elseif var>20 then leave loop_lable;
else select 'v id between 10 and 20';
end if;
end loop loop_lable ;
end;//
call proc7()//

与repeat和while语句不同,loop、leave、iterate更像其他语言中的goto语句。
loop要设定一个lable指定循环开始的位置,而leave则更像其他语言中的break会离开loop指定的块,iterate则会再次回到loop

posted @ 2017-11-04 15:43  测试开发分享站  阅读(131)  评论(0编辑  收藏  举报