Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL视图、储储过程、触发器

MySQL之视图、储储过程、触发器使用及说明

作者:l_tian_tian_

文章介绍了MySQL中的视图、存储过程与触发器:视图是动态生成的虚拟表,用于简化查询和数据访问控制;存储过程是预编译的SQL集合,提升数据处理效率;触发器在表操作前后自动执行,保障数据完整性与操作日志记录

一、视图

视图是一种虚拟存在的表。视图中的数据并不在数据库中真实存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。

通俗的讲,视图只保存了查询的SQL逻辑,不保存查询结果。所以我们在建立视图的时候,主要的工作就落在创建这条SQL查询语句上

创建或修改视图语句:

查看创建视图的语句:

show create view 视图名称;

查看视图:

select * from 视图名称;

删除视图:

drop view if exists 视图名称;

with check option:当使用with check option子句创建视图时,MySQL会通过视图检查正在更改的每个行,例如插入,更新,删除,以使其符合视图定义。MySQL允许基另一个视图创建视图,它还会检查依赖图中的规则保持一致性。

为了确定检查的范围,mysql提供了两个选项:CASCADED和LOCAL,默认值为CASCADED。

无法更新的视图:

作用:

1.视图不仅可以简化用户对数据的理解,也可以简化他们的操作。那些被经常使用的查询可以被定义为视图,从而使用户不必以后操作每次指定全部条件

2.数据库可以授权,但不能授权到数据库特定行和特定的列上。通过视图用户只能查询和修改他们所能见到的数据

3.视图可帮助用户屏蔽真实表结构变化带来的影响

二、存储过程

存储过程是事先经过编译并存储在数据库中的一段SQL语句的集合,调用存储过程可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是有好处的

创建存储过程:

调用:

查询指定数据库的存储过程及状态信息:

select * from information_schema.ROUTINES where ROUTINE_SCHEMA=数据库名称;

查询存储过程定义:

show create procedure 存储过程名称;

删除:

drop procedure if exists 存储过程名称;

注意:在命令行中,执行创建存储过程的SQL时,需要通过关键字delimiter指定SQL语句的结束符

系统变量:是MySQL服务器提供,不是用户定义的,属于服务器层面。分为全局变量(GLOBAL)、会话变量(SESSION)

查看所有系统变量:

show global /session variables ;

通过like模糊匹配方式查找变量:

show global variables like 模糊匹配类型;

查看指定变量:

select @@global.autocommit;

设置系统变量:

set session autocommit=1;

注意:如果没有指定SESSION/GLOBAL,默认是SESSION,会话变量。mysql服务重新启动之后,所设置的全局参数会失效,想要不失效,可在/etc/my.cnf中配置

用户定义变量:是用户根据需要自己定义的变量,用户变量不用提前声明,在用的时候直接用“@ 变量名”使用就可以。其作用域为当前连接。

赋值:

set @name:='李天天';
select sn  into @sn_1 from tb_sku where id=1;

查找:

select @name;

注意:用户定义的变量无需对其进行声明或初始化,只不过获取到地值未NULL

局部变量:是根据需要定义的在局部失效的变量,访问之前,需要DECLARE声明。可用作存储过程内的局部变量和输入参数,局部变量的范围是在其内声明的BEGIN...END块

声明:

 declare total int default 0;

注意:变量类型就是数据库字段类型:INT、BIGINT、CHAR、VARCHAR、DATE、TIME等

赋值:

set total:=90;
 select sn  into total from tb_sku where id=1;

if:

create procedure p1()
begin
    declare score int default 44;
    declare result char(10);
    if score>=80 then
        set result:='优秀';
    elseif score>=60 then
        set result:='良好';
    else
        set result:='不及格';
    end if;
    select result;
end;

参数:

示例:

create procedure p2(in score int,out result char(10))
begin
    if score>=80 then
        set result:='优秀';
    elseif score>=60 then
        set result:='良好';
    else
        set result:='不及格';
    end if;
end;
create procedure p3(inout score double)
begin
   set score:=score*0.5;
end;
set @result=89;
call p3(@result);
select @result;

case:

示例:

begin
    declare season varchar(20);
    case
        when month >= 1 and month <= 3 then set season = '一季度';
        when month >= 4 and month <= 6 then set season = '二季度';
        when month >= 7 and month <= 9 then set season = '三季度';
        when month >= 10 and month <= 12 then set season = '四季度';
        else set season = '输入错误';
        end case;
    select concat('当前月份为:', month, ';当前季度为:', season);

end;

while:

示例:

create procedure p2(in n int)
begin
    declare total int default 0;

    while n > 0
        do
            set total := total + n;
            set n = n - 1;
        end while;
    select concat('累加值为:',total);
end;

repeat:

create procedure p3(in n int)
begin
    declare total int default 0;
    repeat
        set total := total + n;
        set n = n - 1;
    until n <= 0
        end repeat;
    select concat('累加值为:', total);

end;

loop:

loop实现简单的循环,如果不在SQL逻辑中增加退出循环条件,可以用其来实现简单的死循环。loop可以配合一下两个语句使用:

LEAVE:配合循环使用,退出循环

ITERATE:必须用在循环中,作用是跳过当前循环剩下的语句,直接进入下一次循环

create procedure p4(in n int)
begin
    declare total int default 0;
    sum :
    loop
        if n <= 0 then
            leave sum;
        end if;
        set total = total + n;
        set n = n - 1;
    end loop sum;
    select total;
end;
create procedure p6(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;

        else
            set total = total + n;
            set n = n - 1;
        end if;

    end loop sum;
    select total;
end;

游标:

游标是用来存储查询结果集的数据类型,在存储过程和函数中可以使用游标对结果集进行循环的处理。游标的使用包括游标的声明、open、fetch和clode。

声明游标:

打开游标:

获取游标记录:

关闭游标:

条件处理程序:可以用来定义在流程控制结构执行过程中遇到问题时相应的处理步骤

mysql异常状态码文档

https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html

示例:

create procedure p7()
begin
    declare new_name varchar(10) default null;
    declare new_no varchar(10) default null;
    declare student_name cursor for select no,name from student;
    declare exit  handler for SQLSTATE '02000' close student_name;
    open student_name;
    create table if not exists tb_sku_name_price_100
    (
        id   int primary key auto_increment,
        no  varchar(10),
        name varchar(10)


    );
    while true
        do
            fetch student_name into new_no ,new_name ;
            insert into tb_sku_name_price_100 values (null,new_no,new_name);
        end while;

    close student_name;
end;

存储函数:

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

示例:

create function sun(n int)
returns int deterministic
begin
    declare total int default 0;
    while n>0 do
        set total:=n+total;
        set n:=n-1;
        end while;
    return total;
end;

三、触发器

触发器是与表有关的数据库对象,指在insert/update/delete之前或之后,触发并执行触发器中定义的SQL语句集合。触发器的这种特性可以协同应用在数据库端确保数据的完整性,日志记录,数据校验等操作。

使用别名OLD和NEW来引用触发器中发生变化的记录内容,这与其他数据库是相似的。现在数据库还只支持行级触发,不支持语句触发。

创建:

查看:

删除:

insert:

create trigger tb_student_insert_trigger
    after insert on student for each row
    begin
        insert into user_logs (operation, operate_time, operate_id, operate_params) values
        ('insert',now(),new.id,concat('插入的数据内容为:','id为',new.id,'name为',new.name,'no为',NEW.no));
    end;

deleter:

create trigger tb_student_deleter_trigger
    after delete on student for each row
begin
    insert into user_logs (operation, operate_time, operate_id, operate_params) values
        ('deleter',now(),old.id,concat('删除的数据内容为:','id为',old.id,'name为',old.name,'no为',old.no));
end;

update:

create trigger tb_student_update_trigger
    after update on student for each row
begin
    insert into user_logs (operation, operate_time, operate_id, operate_params) values
        ('update',now(),old.id,concat('更新前数据内容为:','id为',old.id,'name为',old.name,'no为',old.no,'|','更新后的数据内容为:','id为',new.id,'name为',new.name,'no为',new.no));
end;

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文