Mysql 存储过程+触发器+存储函数+游标

视图(view)

虚拟存在的表,不保存查询结构,只保存查询的sql逻辑

语法

存储过程

实现定义并存储在数据库的一段sql语句的集合,可减少网络交互,提高性能,代码复用,内容包括:变量,if,case,参数(in/out/inout),循环(while,repeat,loop),游标和handler

存储过程-基本语法

create和call

create procedure p1()
begin 
    select  count(*) from course;
end;
#调用
call p1();

存储过程-系统变量

#系统变量
show  session  variables ; #查看所有系统变量
show session variables like 'auto%';(等价于 show global variables like 'auto%';)
select  @@session.autocommit;#查看指定系统变量
set session autocommit=0;#设置系统变量,关闭自动提交

存储过程-局部变量

局部变量是存在于存储过程中的,通过declare声明局部变量,同时可以在存储过程中给局部变量赋值

#局部变量
create procedure p2()
begin
    declare stu_count int default 0;#说明
    select count(*) into  stu_count from student;#赋值
    select stu_count;#查询
end;
call p2();

存储过程-用户自定义变量

定义用户变量用@

#用户变量
#赋值方式一:推荐使用:=
set @myname='itcast';
set @myage:=10;
set @mygender:='男',@myhobby:='java';
#赋值方式二:通过select
select  @mycolor:='red';
select  count(*) into @mycount from student;
#查看
select @myage,@myname;

存储过程-参数(in,out,inout)

#存储过程参数 in:该类参数作为输入,也就是需要调用时传入值
#          out:该类参数作为输出,也就是该参数可以作为返回值
#          inout:既可以作为输入参数,也可以作为输出参数
#存储过程参数 in:该类参数作为输入,也就是需要调用时传入值
#          out:该类参数作为输出,也就是该参数可以作为返回值
#          inout:既可以作为输入参数,也可以作为输出参数

create procedure p4(in score int,out result varchar(10))
begin
    if score>=85 then
        set  result:='优秀';
        elseif score>=60 then
            set result:='及格';
            else
                set result:='不及格';

        end if;
end;
call p4(99,@result);
select  @result;


create procedure p5(inout score int)
begin
    set score:=score*0.5;
end;
#注意点:out和inout需要传的是变量,不能直接传值!!
set  @score=200;
call p5(@score);
select  @score;

存储过程-case

存储过程-while循环

存储过程-repeat循环

存储过程-loop循环

loop循环和leave,iterate关键字配合使用,leave终止循环(相当于break),iterate结束本次循环(相当于continue)

下面例子 计算的是从1加到10的偶数的和

/*
loop循环
 leave:配合循环使用,退出循环
 iterate:必须用在循环中,作用是跳过当前循环剩下的语句,直接进入下一次
*/
create  procedure  p10(in n int)
begin
    declare total int default 0;
    sum:loop
        if n<=0 then
            leave  sum;
        end if;
        if n%2=1 then
            set n:=n-1;
            iterate sum;
        end if;
        set total:=total+n;
        set n:=n-1;
    end loop sum;
    select total;
end;
call p10(10)

游标和handler

游标的声明,打开,获取,关闭。游标类似二维数组,又不太像,因为游标获取一条记录就同时向新表插入一条记录。游标声明:从基本表中获取哪些字段数据,游标获取:将游标从基本表中获取的每一组字段插入到新表中

游标语法:

Mysql 存储过程+触发器+存储函数+游标_第1张图片

handler类似异常处理,在下面例子中作用是当while循环游标fetch不到下一组数据,反映给handler退出程序。

handler语法:

Mysql 存储过程+触发器+存储函数+游标_第2张图片

 代码练习

create procedure p1(in uage int)
begin
    declare uname varchar(100);
    declare ujob varchar(100);
    #注意游标要在变量之后声明
    declare u_cursor cursor for  select  name,job from emp where age<=uage;
    #handler,处理异常
   # declare exit handler for not found close u_cursor;
    drop  table if exists tb_user_pro;
    create table tb_user_pro(
        id int primary key auto_increment,
        name varchar(100),
        professsion varchar(100)
    );
    #打开游标
    open u_cursor;
    while true do
        fetch u_cursor into uname,ujob;#通过游标获取数据
        insert into tb_user_pro values (null,uname,ujob);
        end while;
    #关闭游标
    close u_cursor;
end;
drop  procedure p1;
call p1(30);

存储函数

存储函数是由返回值的存储过程,存储函数的参数只能是in类型

存储函数语法:

Mysql 存储过程+触发器+存储函数+游标_第3张图片

 代码:

create function f1(n int)
    returns int deterministic
begin
    declare sum int  default 0;
    while n>0 do
        set sum:=sum+n;
        set n:=n-1;

    end while;
    return sum;
end;

select  f1(100);

触发器

触发器是和表相关的数据库对象,指的是在对表进行增删改查操作前后触发并执行触发器中定义的sql语句,触发器能保证数据的完整性,分为insert触发器,delete触发器,update触发器

inserted表:用来存储INSERT和UPDATE语句所影响的行的副本。意思就是在inserted表中临时保存了被插入或被更新后的记录行。在执行 INSERT 或UPDATE 语句时,新加行被同时添加到inserted表和触发器表中。因此,可以从inserted表检查插入的数据是否满足需求,如不满足则回滚撤消操作。

deleted表:用来存储DELETE和UPDATE语句所影响行的副本。意思是在delete表中临时保存了被删除或被更新前的记录行。在执行 DELETE 或 UPDATE 语句时,行从触发器表中删除,并传到deleted表中。所以可以从deleted表中检查删除的数据行是否能删除。
 

触发器语法

Mysql 存储过程+触发器+存储函数+游标_第4张图片

 插入触发器

问题:我们要向表tb_user插入数据,希望在日志表中看到插入后的新记录是什么

 解决:每向表tb_user插入一次,就执行一次insert触发器中的sql语句

代码

create table user_logs(
    id int(11) not null auto_increment primary key,
    operation varchar(20) not null  comment '操作类型,增/删/改',
    operation_time datetime not null comment '操作时间',
    operation_id int(11) not null comment '操作的id',
    operation_params varchar(500) comment '操作参数'

)engine =innodb default charset utf8;

-- 插入数据触发器
create trigger tb_user_insert_trigger
    after insert on tb_user for each row

begin
        insert into user_logs(id, operation, operation_time, operation_id, operation_params)
            VALUES(null,'insert',now(),new.id,concat('插入的内容为:id=',new.id,',name=',NEW.name,',age=',NEW.age));
end;
show triggers ;
insert into tb_user(id, name, age) VALUES (null,'小何',54);

 修改触发器


-- 修改数据触发器
-- 要在日志表中展示修改前后的数据
create trigger tb_user_update_trigger
    after update on tb_user for each row

begin
        insert into user_logs(id, operation, operation_time, operation_id, operation_params)
            VALUES(null,'update',now(),new.id,
                   concat('更新前的内容为:id=',OLD.id,',name=',OLD.name,',age=',OLD.age,
                   '更新后的内容为:id=',new.id,',name=',NEW.name,',age=',NEW.age)
                   );
end;
show triggers ;

update tb_user set name='小林' where id=4;

 删除触发器

create trigger tb_user_delete_trigger
    before delete on tb_user for each row
begin
              insert into user_logs(id, operation, operation_time, operation_id, operation_params)
            VALUES(null,'delete',now(),OLD.id,
                   concat('删除前的内容为:id=',OLD.id,',name=',OLD.name,',age=',OLD.age));
end;

show triggers ;
delete from  first.tb_user where id=4;

你可能感兴趣的:(MySQL,mysql,数据库,java)