文章目录
- MYSQL开发-存储过程、触发器
- 1. 存储过程
- 1.1 存储过程的定义和调用
- 1.2 存储过程的参数介绍
- 2. 触发器
MYSQL开发-存储过程、触发器
1. 存储过程
1.1 存储过程的定义和调用
存储过程可以看作是为实现某个功能而设计的sql代码块。存储过程在创建的时候已经编译,在执行和调用的时候效率极高。一次编译,多次调用。
优点:
①增强sql语言的功能和灵活性
②标准组件式编程
③较快的执行速度
④减少网络流量
⑤实现访问权限的控制
缺点:
①可移植性差
②对于简单的sql语句不适用存储过程。
③团队开发应统一标准。
④业务逻辑复杂时,使用存储过程效果不明显。
⑤在并发访问较大时,不适合写涉及过多运算的存储过程。
修改sql语句默认结束符;【在mysql中,分号是sql语句的默认结束符,在创建存储过程时,会因为分号报错。】【语法:delimiter %
】【在创建存储过程后,恢复默认结束符为分号;】
定义存储过程:
-- 存在则删除【生产的时候慎用,以免误删除】
drop procedure if exists proc_name;
-- 创建存储过程
create procedure proc_name(参数1,参数2)
begin
sql sentences;
end;
-- 执行存储过程
call proc_name(参数1,参数2);
-- 创建一个无参数的存储过程
delimiter %
create procedure insert_proc()
begin
select * from test;
end%
delimiter ; -- 恢复默认结束符为分号;
-- 执行存储过程
call insert_proc() %
1.2 存储过程的参数介绍
in参数:
-- in 参数:外部传值给存储过程使用
-- (in id int)
delimiter %
create procedure proc_id(in id int,in name char(20))
begin
insert into test values(id,name);
end%
out参数:
-- out 参数:将存储过程的执行结果回传给其他调用它的程序使用
-- (out name varchar(10))
delimiter %
create procedure proc_name(in var_id int,out var_name char(20))
begin
select name into @var_name from test where id=var_id;
select @var_name as '姓名';
end%
delimiter ;
在执行前,要声明一个局部变量,而局部变量要赋予初始值,用来接收存储过程的输出。
inout参数:
-- inout参数:外部传值给存储过程使用,然后存储过程把执行结果回传给其他调用它的程序使用。
-- (inout num int)
delimiter %
create procedure proc_power(inout num int)
begin
set num=num*num;
select num;
end%
delimiter ;
存储过程中变量的使用:
-- 变量声明
create procedure proc_name()
begin
delcare var_name var_type [default 默认值];
sql语句
end;
delimiter %
drop procedure if exists proc_name%
create procedure proc_name(in var_id int)
begin
declare var_name char(20);
set var_name=(select name from test where id=var_id);
select var_name as name;
end%
delimiter ;
变量作用域:
-- 内部存储过程的变量a对外部存储过程是不可见的
begin -- 外部存储过程
declare a int;
begin -- 内部存储过程
declare a int;
end;
end;
-- 创建存储过程
delimiter %
drop procedure if exists proc_test%
create procedure proc_test()
begin
declare a int default 1;
begin
declare a int default 2;
select a;
end;
select a;
end%
delimiter ;
-- 执行存储过程
call proc_test();
可以看到,第一个查询结果是内部存储过程的变量,第二个是外部存储过程的变量。
流程控制语句:
①条件语句
-- 创建存储过程
delimiter %
drop procedure if exists bjdx%
create procedure bjdx(in a int,in b int)
begin
declare answer varchar(20);
if a>b then
set answer='a';
elseif a<b then
set answer='b';
else
set answer='ab';
end if;
select answer;
end%
delimiter ;
-- 执行存储过程
call bjdx(1,2);
②case语句
-- case语法
case col_name
when 值1 then
操作1;
when 值2 then
操作2;
else
操作3;
end case;
-- 输入1234得四季
delimiter %
drop procedure if exists proc_sea%
create procedure proc_sea(in sea int)
begin
declare season varchar(10);
case sea
when 1 then
set season='spring';
when 2 then
set season='summer';
when 3 then
set season='autumn';
when 4 then
set season='winter';
else
set season='no sea';
end case;
select season;
end%
delimiter ;
③循环语句【while\repeat\loop
】
while循环:先判断再循环
-- while循环语法
while 条件表达式
do
循环体
end while;
-- 求前100个自然数的和
delimiter %
drop procedure if exists proc_sum%
create procedure proc_sum(in count int)
begin
declare s int;
declare i int;
set s=0;
set i=1;
while i<=count
do
set s=s+i;
set i=i+1;
end while;
select s;
end%
delimiter ;
-- 执行存储过程
call proc_sum(100);
repeat循环:先循环再判断
-- repeat循环语法
repeat
循环体
until 条件
end repeat;
-- 求前100个自然数的和
delimiter %
drop procedure if exists proc_sum%
create procedure proc_sum(in count int)
begin
declare s int;
declare i int;
set s=0;
set i=0;
repeat
set i=i+1;
set s=s+i;
until i>=count
end repeat;
select s;
end%
delimiter ;
-- 执行存储过程
call proc_sum(100);
loop循环:先循环再判断
-- loop循环语法
loop_name:loop
循环体
if 条件 then -- 用一个if判断来结束循环
leave loop_name;
end if;
end loop;
-- 求前100个自然数的和
delimiter %
drop procedure if exists proc_sum%
create procedure proc_sum(in count int)
begin
declare s int;
declare i int;
set s=0;
set i=0;
loop_name:loop
set i=i+1;
set s=s+i;
if i>=count then
leave loop_name;
end if;
end loop;
select s;
end%
delimiter ;
-- 执行存储过程
call proc_sum(100);
查看有什么存储过程及存储过程的内容:
-- 查看某个存储过程的内容
show create procedure proc_name\G;
-- 查看所有的存储过程
show procedure status\G;
-- 删除存储过程:
drop procedure proc_name;
drop procedure if exists proc_name
-- 在一个存储过程中,允许调用另一个存储过程,但是不允许删除另一个存储过程。
2. 触发器
-- 创建触发器的格式
delimiter %
create trigger tri_name
[before | after] tri_event
on table_name | view_name | user_name | db_name
[for each row][when tri_condition]
sql语句
%
tri_event一般指DML语句,即insert delete update
设计一个触发器,在删除dept表中某行数据时,也相应删除emp中的数据。
-- 创建触发器
delimiter %
create trigger tri_emp_dept
after delete
on dept
for each row
delete from emp where deptno=OLD.id; -- OLD指旧行,即在dept表上执行delete操作所对应的行。
%
-- 测试触发器效果
delimiter ;
delete from dept where id=10;
查看某个触发器的内容:
查看所有的触发器:
-- 删除触发器
drop trigger tri_name;
drop trigger if exists tri_name;
如果对mysql存储过程和触发器不是太了解的,可以参考下ORACLE存储过程和触发器,相互验证,加深理解。