MYSQL开发-存储过程、触发器

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
when1 then 
操作1;
when2 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存储过程和触发器,相互验证,加深理解。

猜你喜欢

转载自blog.csdn.net/weixin_36522099/article/details/108523279
今日推荐