MySQL视图/存储器/触发器

菜鸡自用

orz

视图

视图的定义

视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列 数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。

引入视图的原因

视图是存储在数据库中的查询的SQL 语句,它主要出于两种原因:

安全原因, 视图可以隐藏一些数据,如:社会保险基金表,可以用视图只显示姓名,地址,而不显示社会保险号和工资数等,

另一原因是可使复杂的查询易于理解和使用。

或者可以数据独立,帮助用户屏蔽真实表结构变化带来的影响

视图的基础语法

#创建视图的语法
create [or replace] view 视图名称[列名列表] as select 语句 [with [cascaded/ local] check option];

#查询
#查看创建视图的语句
show create view 视图名称;

#查看视图数据 
select * from 视图名称;

#需改
1. create [or replace] view 视图名称[列名列表] as select 语句 [with [cascaded/ local] check option];

2.alter view 视图名称[列名列表] as select 语句 [with [cascaded/ local] check option];


#删除
drop view if exists 视图名称;

#创建视图
create or replace view stu_v_1 as select id, name from student where id <= 20 with cascaded check option;

select * from stu_v_1;

insert into stu_v_1 values(6, "tom"); //可插入
insert into stu_v_1 values(30, "tom"); //不可插入 30 > 20

检查选项(cascaded, local)

当使用WITH CHECK OPTION子句创建视图时,MySQL会通过视图检查正在更改的每个行,例如 插入,更新,删除,以使其符合视图的定义。 MySQL允许基于另一个视图创建视图,它还会检查依赖视图中的规则以保持一致性。为了确定检查的范围,mysql提供了两个选项:CASCADED 和 LOCAL ,默认值为 CASCADED 。

两个如果依赖上一个视图,就要递归上去。

1.cascade

#表1
create or replace view stu_v_1 as select id, name from student where id <= 20;

insert into stu_v_1 values (10, "tom"); //可插入,没有检查选项

insert into stu_v_1 values (20, "tom"); //可插入,没有检查选项


#表2
create or replace view stu_v_2 as select id, name from stu_v_1 where id >= 10;

insert into stu_v_2 values (7, "tom"); //不可插入,检查选项

insert into stu_v_2 values (26, "tom"); //不可插入,检查选项,同时给上面的表赋予with cascaded check option;

insert into stu_v_2 values (15, "tom"); //可插入,检查选项


#表3
create or replace view stu_v_3 as select id, name from stu_v_2 where id >= 15;

insert into stu_v_3 values (17, "tom"); //可插入,检查选项表2和表1

insert into stu_v_1 values (7, "tom"); //可插入,检查选项表2不满足

2.local

向上递归需要依赖的视图,检查选项只作用于本条语句。

#表1
create or replace view v1 as select id,name from students where id <= 20;

insert into v1 values(21,'john');//插入成功,没有检查选项

#表2
#创建一个基于表1的视图,并添加local检查选项
create or replace view v2 as select id,name from v1 where id > 10 with local check option;

#添加检查选项后,再插入数据,MySQL就会判断插入数据是否满足条件,
insert into v2 values(22,'lucy');//检查选项,满足,向上递归

#表2
#创建一个基于表2的视图
create or replace v3 as select id,name from v2 where id <= 15;

#由于v3没有添加检查选项,但v3是基于v2的,所以现在可以插入的id值依然为 id > 10。
insert into v3 values(18,'Tom');#插入成功

视图的更新

 存储过程

阿里开发规范禁用存储过程,看自己来吧....

简介

型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来调用存储过程。. 简单的说就是专门干一件事一段sql语句可以由数据库自己去调用,也可以由java程序去调用。 在oracle数据库中存储过程是procedure

基本语法

#创建存储过程
create procedure p1()
begin
		select count(*) from `user`;
end;

#调用存储过程
call p1();

#查看
select * from information_schema.ROUTINES WHERE ROUTINE_SCHEMA= "reggie" 

show create procedure p1;

#删除
drop PROCEDURE if EXISTS p1;

查看的展示

 小tips

在命令行中,执行创建存储过程的SQL时,需要通过delimiter指定SQL语句结束符.

变量

1.系统变量

系统变量是MySQL提供的,不被用户定义属于服务器层面,分为全局变量BLOBAL,会话变量Session

//查看系统变量
show session/global variables //查看所有系统变量

show session/global variables like “%” //模糊匹配查询

select @@session/global 系统变量名//精确查找

//设置系统变量
set session/global 系统变量名 = 值
set @@session/global 系统变量名 = 值

Tips:没有指定session/global,默认是session

        mysql服务器重启后,所设置的全局参数会失效,如果不想失效,去/etc/my.cnf配置

2.用户变量

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

@ABC,ABC未声明,可以使用,默认是NULL

#赋值
set @yname = "scy";

set @yage := 10;

set @ygender := '男', @yhobby := 'java';

select @mycolor := 'red';
select count(*) into @mycount from tb_user;


@使用
select @mycolor, mycount;

3.局部变量

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

create PROCEDURE p2()
BEGIN
 DECLARE stu_count int default 0;
 select count(*) into stu_count from user;
 select stu_count;
end;

call p2();

参数

1.if

没参数,感觉有点像语法,所以加里面

  

#根据分数,返回等级

create procedure p3()
begin
    declare score int default 58;
    declare result varchar(10);


    if score >= 85 then
            set result := "优秀";

    elseif score >=60 then
            set result := "及格";
    else   
            set result := "不及格"

    end if
    select result;
end;


call p3();

2.in, out , inout

输入,输出,可输入可输出

#1
create procedure p4(int 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(46, @result);


select @result;
    

#2 二百分转成百分制

create procedure p5(inout score double)
begin 
    set score := score * 0.5;
end;

set @score = 120;
call p5(@score);
select @score;

3.case

根据月份判断季度,没什么意思,直接上图了

 4.while

create procedure p7(in n int)
begin
	declare total int default 0;
	while n>0 do
				set total := total + n;
				set n := n - 1;
	end while;
	select total;
end;

call p7(10);

5.repeat

满足条件退出循环和上面的区分一下就行。

 6.loop

loap实现简单的循环,如果不在SQL逻辑中增加退出循环的条件,可以用来实现死循环,loop可以配和以下两个语句.

leave:配和循环,退出循环

iterate:跳过当前循环,直接进入下一次循环

没什么意义,到时候看笔记就行

 7.cursor

改天补上

#声明游标
declare 游标名称 cursor for 查询语句;

#打开游标
open 游标名称;

#打开游标记录
fetch 游标名称 into 变量,变量;

#关闭游标
close 游标名称;
create procedure p11(int uage int)
begin
    declear uname varchar(100); //先声明普通变量,在声明游标
    declear upro varchar(100);
    declear u_cursor cursor for select name, profession from tb_user where age <= uage;
    
    drop table if exists tb_user_pro;

    create table if not exists tb_user_pro(
                id int primary key auto_increment;
                name varchar(100),
                profession varchar(100)
    );


    open u_cursor;
    
    with true do
        fetch u_cursor into uname, upro;
        
        insert into tb_user_pro values(null, uname, upro);
    end while;
    
    close u_cursor;

end;

Handler

异常来跳出循环,多少优点抽象。。。

create procedure p11(int uage int)
begin
    declear uname varchar(100); //先声明普通变量,在声明游标
    declear upro varchar(100);
    declear u_cursor cursor for select name, profession from tb_user where age <= uage;//声明游标
    declare exit handler for SQLSTATE '02000' close u_cursor;
    
    drop table if exists tb_user_pro; //检查有无表

    create table if not exists tb_user_pro(//创建表
                id int primary key auto_increment;
                name varchar(100),
                profession varchar(100)
    );


    open u_cursor; //开启游标
    
    with true do //遍历赋值给表
        fetch u_cursor into uname, upro;
        
        insert into tb_user_pro values(null, uname, upro);
    end while;
    
    close u_cursor; //关闭游标

end;

存储函数 

没什么意思,看看就行

触发器

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

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

栗子:一条update更新了5条语句,那触发器就执行5次,这就是行级触发器,语句级的话就执行一次。

触发器类型

       INSERT型触发器:NEW表示将要或者已经新增的数据

       UPDATE型触发器:OLD表示修改之前的数据,NEW表示将要或者已经修改后的数据

        DELETE型触发器:OLD表示将要或者已经修改后的数据

1.insert

#创建表
create table user_logs(
	id int(11)not null auto_increment,
	operation varchar(20) not null comment'操作类型,insert/update/delete' ,
	operate_time datetime not null comment "操作时间",
	operate_id int(11) not null comment '操作的ID',
	operate_params varchar(500) comment '操作参数',
	primary key(id )
)engine=innodb default charset=utf8;


#创建触发器
create trigger tb_user_insert_trigger
	after insert on users for each ROW
begin
	insert into user_logs (id,operation,operate_time,operate_id,operate_params)
	VALUES
	(1,'insert', now(), new.id,concat('插入的数据内容为: id=' , new.id ,' , name=' , new.username));
end;		 

#查看触发器
show triggers;

#删除触发器
drop trigger tb_user_insert_trigger

#插入结果
insert into users VALUES (3, "张三", '123242');

#查看表的创建语句
show create TABLE users

select * from user_logs

触发器展示

结果展示

2.update

#创建表
create table user_logs(
	id int(11)not null auto_increment,
	operation varchar(20) not null comment'操作类型,insert/update/delete' ,
	operate_time datetime not null comment "操作时间",
	operate_id int(11) not null comment '操作的ID',
	operate_params varchar(500) comment '操作参数',
	primary key(id )
)engine=innodb default charset=utf8;


#创建触发器
create trigger tb_user_update_trigger
	after update on users for each ROW
begin
	insert into user_logs (id,operation,operate_time,operate_id,operate_params)
	VALUES
	(null,'update', now(), new.id, concat('更新之前的数据内容为: id=' , old.id ,' , name=' , old.username, '更新之后的数据内容为: id=' , new.id ,' , name=' , new.username));
end;

update users set username = "张某某" where id = 1;

3.delete

create trigger tb_user_delete_trigger
	after delete on users for each ROW
begin
	insert into user_logs (id,operation,operate_time,operate_id,operate_params)
	VALUES
	(null,'update', now(), old.id, concat('更新之前的数据内容为: id=' , old.id ,' , name=' , old.username));
end;

delete from users where id = 1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值