• 视图、存储过程、触发器


    视图

    视图(View) 是一种虚拟存在的表。视图中的数据并不在数据库中实际存在, 行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。视图值保存了查询的SQL逻辑,不保存查询结果。

    1. 视图基本操作

    1. -- 创建视图
    2. create view stu_v_1 as select id,name from student where id <=20;
    3. -- 查看视图创建语句
    4. show CREATE view stu_v_1
    5. -- 修改视图
    6. CREATE or REPLACE view stu_v_1 as SELECT * from student;
    7. alter view stu_v_1 as SELECT * from student;
    8. -- 删除视图
    9. drop view stu_v_1;

    2. 视图检查选项CASCADED

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

    CASCADE: 不管关联视图的是否开启视图检查,都需要判断是否满足插入条件

    1. SELECT * from student;
    2. create view v1 as SELECT id,name from student where id <=20;
    3. insert into v1 VALUES (5,'Tom');
    4. insert into v1 VALUES (25,'Tom');
    5. create view v2 as SELECT id,name from v1 where id >=10 with CASCADED check OPTION;
    6. insert into v2 VALUES (6,'Tom');
    7. insert into v2 VALUES (11,'Tom');
    8. -- id为21插入失败的原因是,v2视图是通过v1视图查询出来的,且用到了cascaded(级联),不仅需要检测v2的条件,还要检测v1的条件
    9. insert into v2 VALUES (21,'Tom');
    10. create view v3 as SELECT id,name from v2 where id >=15;
    11. insert into v3 VALUES (16,'Tom');
    12. insert into v3 VALUES (7,'Tom');
    13. -- id为22插入v3失败的原因是,v3视图是通过v2视图查询出来的,需要检测v2的条件,且v2又和v1有级联,所以v1,v2,v3三个视图的条件都要进行检测
    14. insert into v3 VALUES (22,'Tom');

    LOCAL:和CASCADE不同的是,进行视图检查时,会去看关联的表有没有开启视图检查,如果没有开启视图检查,则不需要判断关联表的条件

    1. create view v4 as SELECT id,name from student where id <=20;
    2. insert into v4 VALUES (5,'Tom');
    3. insert into v4 VALUES (25,'Tom');
    4. create view v5 as SELECT id,name from v4 where id >=10 with CASCADED LOCAL OPTION;
    5. insert into v5 VALUES (6,'Tom');
    6. -- 这里的id=11,如果是local的话,就可以进行插入,因为虽然关联了v4,但v4没有开启视图检查,所以只需满足v5视图的条件即可
    7. insert into v5 VALUES (11,'Tom');
    8. create view v6 as SELECT id,name from v2 where id >=15
    9. insert into v6 VALUES (16,'Tom');
    10. -- 这里的id=22同样可以插入,因为虽然关联了v5,v5虽然有视图检查,但是id满足条件,且v5关联的v4没有开启视图检查,所以只需满足v5,v6视图的条件即可
    11. insert into v6 VALUES (22,'Tom');

    3. 视图的更新

      

     存储过程

    1. 基本语法 

     

    1. -- 创建存储过程
    2. CREATE PROCEDURE p1()
    3. BEGIN
    4. SELECT count(*) from tb_user;
    5. END
    6. -- 调用
    7. call p1()
    8. -- 查看
    9. SELECT * from information_schema.ROUTINES where ROUTINE_SCHEMA = 'itcast'
    10. show create PROCEDURE p1;
    11. -- 删除
    12. DROP PROCEDURE IF EXISTS P1;

    2. 变量 

     变量主要分为三种:系统变量、用户自定义变量和局部变量。

    系统变量

    1. -- 查看系统变量
    2. show session variables ;
    3. show session variables like 'auto%';
    4. show global variables like 'auto%';
    5. select @@global.autocommit;
    6. select @@session.autocommit;
    7. -- 设置系统变量
    8. set session autocommit = 1;
    9. insert into course(id, name) VALUES (6, 'ES');
    10. set global autocommit = 0;
    11. select @@global.autocommit;

    用户自定义变量 

    1. -- 变量: 用户变量
    2. -- 赋值
    3. set @myname = 'itcast';
    4. set @myage := 10;
    5. set @mygender := '男',@myhobby := 'java';
    6. select @mycolor := 'red';
    7. select count(*) into @mycount from tb_user;
    8. -- 使用
    9. select @myname,@myage,@mygender,@myhobby;
    10. select @mycolor , @mycount;
    11. select @abc;

    局部变量

    1. -- 变量: 用户变量
    2. -- 赋值
    3. set @myname = 'itcast';
    4. set @myage := 10;
    5. set @mygender := '男',@myhobby := 'java';
    6. select @mycolor := 'red';
    7. select count(*) into @mycount from tb_user;
    8. -- 使用
    9. select @myname,@myage,@mygender,@myhobby;
    10. select @mycolor , @mycount;
    11. select @abc;

    3. if 条件判断

    if条件判断需求 

    1. create procedure p3()
    2. begin
    3. declare score int default 58;
    4. declare result varchar(10);
    5. if score >= 85 then
    6. set result := '优秀';
    7. elseif score >= 60 then
    8. set result := '及格';
    9. else
    10. set result := '不及格';
    11. end if;
    12. select result;
    13. end;
    14. call p3();

    4. 存储过程-参数(IN/OUT) 

     

    需求: 

     

    1. -- in/out/inout参数
    2. -- 根据传入(in)参数score,判定当前分数对应的分数等级,并返回(out)。
    3. -- score >= 85分,等级为优秀。
    4. -- score >= 60分 且 score < 85分,等级为及格。
    5. -- score < 60分,等级为不及格。
    6. create procedure p4(in score int, out result varchar(10))
    7. begin
    8. if score >= 85 then
    9. set result := '优秀';
    10. elseif score >= 60 then
    11. set result := '及格';
    12. else
    13. set result := '不及格';
    14. end if;
    15. end;
    16. call p4(18, @result);
    17. select @result;
    18. -- 将传入的 200分制的分数,进行换算,换算成百分制 , 然后返回分数 ---> inout
    19. create procedure p5(inout score double)
    20. begin
    21. set score := score * 0.5;
    22. end;
    23. set @score = 198;
    24. call p5(@score);
    25. select @score;

    5. 存储过程- 循环 

    while

    while循环是满足条件后,再执行循环体中的SQL语句,对应Java中的while语法

    1. -- while 计算从1累加到n的值,n为传入的参数值。
    2. -- A. 定义局部变量, 记录累加之后的值;
    3. -- B. 每循环一次, 就会对n进行减1 , 如果n减到0, 则退出循环
    4. create procedure p7(in n int)
    5. begin
    6. declare total int default 0;
    7. while n>0 do
    8. set total := total + n;
    9. set n := n - 1;
    10. end while;
    11. select total;
    12. end;
    13. call p7(100);

    repeat 

    对应Java中的do while语法

    1. -- repeat 计算从1累加到n的值,n为传入的参数值。
    2. -- A. 定义局部变量, 记录累加之后的值;
    3. -- B. 每循环一次, 就会对n进行-1 , 如果n减到0, 则退出循环
    4. create procedure p8(in n int)
    5. begin
    6. declare total int default 0;
    7. repeat
    8. set total := total + n;
    9. set n := n - 1;
    10. until n <= 0
    11. end repeat;
    12. select total;
    13. end;
    14. call p8(10);
    15. call p8(100);

    loop

    对应Java中的死循环,leave对应break,iterate对应continue 

    1. -- loop需求1 计算从1累加到n的值,n为传入的参数值。
    2. -- A. 定义局部变量, 记录累加之后的值;
    3. -- B. 每循环一次, 就会对n进行-1 , 如果n减到0, 则退出循环 ----> leave xx
    4. create procedure p9(in n int)
    5. begin
    6. declare total int default 0;
    7. sum:loop
    8. if n<=0 then
    9. leave sum;
    10. end if;
    11. set total := total + n;
    12. set n := n - 1;
    13. end loop sum;
    14. select total;
    15. end;
    16. -- loop需求2 计算从1到n之间的偶数累加的值,n为传入的参数值。
    17. -- A. 定义局部变量, 记录累加之后的值;
    18. -- B. 每循环一次, 就会对n进行-1 , 如果n减到0, 则退出循环 ----> leave xx
    19. -- C. 如果当次累加的数据是奇数, 则直接进入下一次循环. --------> iterate xx
    20. create procedure p10(in n int)
    21. begin
    22. declare total int default 0;
    23. sum:loop
    24. if n<=0 then
    25. leave sum;
    26. end if;
    27. if n%2 = 1 then
    28. set n := n - 1;
    29. iterate sum;
    30. end if;
    31. set total := total + n;
    32. set n := n - 1;
    33. end loop sum;
    34. select total;
    35. end;
    36. call p10(100);

    6. 存储过程-游标

    1. -- 游标
    2. -- 根据传入的参数uage,来查询用户表 tb_user中,所有的用户年龄小于等于uage的用户姓名(name)和专业(profession),
    3. -- 并将用户的姓名和专业插入到所创建的一张新表(id,name,profession)中。
    4. -- 逻辑:
    5. -- A. 声明游标, 存储查询结果集
    6. -- B. 准备: 创建表结构
    7. -- C. 开启游标
    8. -- D. 获取游标中的记录
    9. -- E. 插入数据到新表中
    10. -- F. 关闭游标
    11. create procedure p11(in uage int)
    12. begin
    13. declare uname varchar(100);
    14. declare upro varchar(100);
    15. declare u_cursor cursor for select name,profession from tb_user where age <= uage;
    16. declare exit handler for SQLSTATE '02000' close u_cursor;
    17. drop table if exists tb_user_pro;
    18. create table if not exists tb_user_pro(
    19. id int primary key auto_increment,
    20. name varchar(100),
    21. profession varchar(100)
    22. );
    23. open u_cursor;
    24. while true do
    25. fetch u_cursor into uname,upro;
    26. insert into tb_user_pro values (null, uname, upro);
    27. end while;
    28. close u_cursor;
    29. end;
    30. call p11(30);

    7. 存储函数

    存储函数和存储过程的区别在于,只能有IN参数,且必须有返回值。

    1. -- 存储函数
    2. -- 从1到n的累加
    3. create function fun1(n int)
    4. returns int deterministic
    5. begin
    6. declare total int default 0;
    7. while n>0 do
    8. set total := total + n;
    9. set n := n - 1;
    10. end while;
    11. return total;
    12. end;
    13. select fun1(50);

     触发器

    1. -- 触发器
    2. -- 需求: 通过触发器记录 user 表的数据变更日志(user_logs) , 包含增加, 修改 , 删除 ;
    3. -- 准备工作 : 日志表 user_logs
    4. create table user_logs(
    5. id int(11) not null auto_increment,
    6. operation varchar(20) not null comment '操作类型, insert/update/delete',
    7. operate_time datetime not null comment '操作时间',
    8. operate_id int(11) not null comment '操作的ID',
    9. operate_params varchar(500) comment '操作参数',
    10. primary key(`id`)
    11. )engine=innodb default charset=utf8;
    12. -- 插入数据触发器
    13. create trigger tb_user_insert_trigger
    14. after insert on tb_user for each row
    15. begin
    16. insert into user_logs(id, operation, operate_time, operate_id, operate_params) VALUES
    17. (null, 'insert', now(), new.id, concat('插入的数据内容为: id=',new.id,',name=',new.name, ', phone=', NEW.phone, ', email=', NEW.email, ', profession=', NEW.profession));
    18. end;
    19. -- 查看
    20. show triggers ;
    21. -- 删除
    22. drop trigger tb_user_insert_trigger;
    23. -- 插入数据到tb_user
    24. insert into tb_user(id, name, phone, email, profession, age, gender, status, createtime) VALUES (26,'三皇子','18809091212','erhuangzi@163.com','软件工程',23,'1','1',now());
    25. -- 修改数据触发器
    26. create trigger tb_user_update_trigger
    27. after update on tb_user for each row
    28. begin
    29. insert into user_logs(id, operation, operate_time, operate_id, operate_params) VALUES
    30. (null, 'update', now(), new.id,
    31. concat('更新之前的数据: id=',old.id,',name=',old.name, ', phone=', old.phone, ', email=', old.email, ', profession=', old.profession,
    32. ' | 更新之后的数据: id=',new.id,',name=',new.name, ', phone=', NEW.phone, ', email=', NEW.email, ', profession=', NEW.profession));
    33. end;
    34. show triggers ;
    35. update tb_user set profession = '会计' where id = 23;
    36. update tb_user set profession = '会计' where id <= 5;
    37. -- 删除数据触发器
    38. create trigger tb_user_delete_trigger
    39. after delete on tb_user for each row
    40. begin
    41. insert into user_logs(id, operation, operate_time, operate_id, operate_params) VALUES
    42. (null, 'delete', now(), old.id,
    43. concat('删除之前的数据: id=',old.id,',name=',old.name, ', phone=', old.phone, ', email=', old.email, ', profession=', old.profession));
    44. end;
    45. show triggers ;
    46. delete from tb_user where id = 26;

  • 相关阅读:
    dragTabs(vue)
    接口测试工具
    正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-1.3
    一次联合编译器问题排查(备忘)
    淘宝/天猫API:img2text-图片识别商品接口
    FactoryBean解读
    华为机试真题 Java 实现【查找众数及中位数】
    Centos7 离线安装docker
    计算机的应用领域
    spark实验求TOP值
  • 原文地址:https://blog.csdn.net/qq_59212867/article/details/133894440