
create database if not exists bilibili; #创建数据库bilibili
use bilibili; #选择bilibili数据库，即可进行下面的代码演示
drop database if exists bilibili; #代码演示结束后删除bilibili数据库。这个小文件全部代码演示完再删
show databases;  #查看是否删除完成

-- 准备数据
create table tb_user(
    id int auto_increment primary key comment '主键ID',
    name varchar(10) comment '姓名',
    phone char(11) comment '手机号',
    email varchar(40) comment '邮箱',
    profession varchar(20) comment '专业',
    age int comment '年龄',
    gender int comment '性别',
    status int comment '状态',
    createtime date comment '创建时间'
) comment '用户信息表';
insert into tb_user(id,name,phone,email,profession,age,gender,status,createtime) values
         (null,'吕布',17799990000,'1vbu666@163.com','软件工程',23,1,6,'2001-02-02 00:00:00'),#id字段不用指定，我们设置了自增
         (null,'曹操',17799990001,'caocao666@qq.com','通讯工程',33,1,0,'2001-03-05 00:00:00'),
         (null,'赵云',17799990002,'17799990@139.com','英语',34,1,2,'2001-03-02 00:00:00'),
         (null,'孙悟空',17799990003,'17799990@sina.com','工程造价',54,1,0,'2001-07-02 00:00:00'),
         (null,'花木兰',17799990004,'19980729@sina.com','软件工程',23,2,1,'2001-04-22 00:00:00'),
         (null,'大乔',17799990005,'daqiao666@sina.com','舞蹈',22,2,0,'2001-02-07 00:00:00'),
         (null,'露娜',17799990006,'luna_love@sina.com','应用数学',24,2,0,'2001-08-02 00:00:00'),
         (null,'程咬金',17799990007,'chengyaojin@163.com','化工',38,1,5,'2001-05-23 00:00:00'),
         (null,'项羽',17799990008,'xiaoyu666@qq.com','金属材料',43,1,0,'2001-9-18 00:00:00'),
         (null,'白起',17799990009,'baiqi666@sina.com','机械工程及其自动化',27,1,2,'2001-08-16 00:00:00'),
         (null,'韩信',17799990010,'hanxin520@163.com','无机非金属材料工程',27,1,0,'2001-06-12 00:00:00'),
         (null,'荆轲',17799990011,'jingke123@163.com','会计',29,1,0,'2001-05-11 00:00:00'),
         (null,'兰陵王',17799990012,'lanlinwang666@126.com','工程造价',44,1,1,'2001-04-09 00:00:00'),
         (null,'狂铁',17799990013,'kuangtie@sina.com','应用数学',43,1,2,'2001-04-10 00:00:00'),
         (null,'貂蝉',17799990014,'84958948374@qq.com','软件工程',40,2,3,'2001-02-12 00:00:00'),
         (null,'妲己',17799990015,'2783238293@qq.com','软件工程',31,2,0,'2001-01-30 00:00:00'),
         (null,'芈月',17799990016,'xiaomin2001@sina.com','工业经济',35,2,0,'2000-05-03 00:00:00'),
         (null,'嬴政',17799990017,'8839434342@qq.com','化工',38,1,1,'2001-08-08 00:00:00'),
         (null,'狄仁杰',17799990018,'jujiamlm0166@163.com','国际贸易',30,1,0,'2007-03-12 00:00:00'),
         (null,'安琪拉',17799990019,'jdodmlh@126.com','城市规划',51,2,0,'2001-08-15 00:00:00'),
         (null,'典韦',17799990020,'ycaunanjian@163.com','城市规划',52,1,2,'2000-04-12 00:00:00'),
         (null,'廉颇',17799990021,'lianpo321@126.com','土木工程',19,1,3,'2002-07-18 00:00:00'),
         (null,'后裔',17799990022,'altycj2000@139.com','城市园林',20,1,0,'2002-03-10 00:00:00'),
         (null,'姜子牙',17799990023,'37483844@qq.com','工程造价',29,1,4,'2003-05-26 00:00:00');

-- -------------------------------------------触发器 介绍---------------------------------------------------------

/*触发器
是与表有关的数据库对象，指在 insert/update/delete 之前或之后，触发并执行触发器中定义的SQL语句集合。触发器的这种特性可以
协助应用在数据库端确保数据的完整性，日志记录，数据校验等操作。
使用别名 old 和 new 来引用触发器中发生变化的记录内容，这与其他的数据库是相似的。现在触发器还只支持行级触发，不支持语句级触发

行级触发: 例如我们执行一条update语句，该语句影响了5行，那么触发器会被触发5次，该触发器就叫行级触发器
语句级触发: 例如我们执行一条update语句，不管该语句影响了几行，触发器只触发1次，该触发器就叫语句级触发器

触发器类型                    old和new
insert型触发器               new表示将要或者已经新增的数据
update型触发器               old表示修改之前的数据，new表示将要或已经修改后的数据
delete型触发器               old表示将要或者已经删除的数据

触发器语法如下。触发器可以在增删改之前或之后触发

创建
create trigger trigger_name
before/after insert/update/delete
on tbl_name for each row #行级触发器
begin
         trigger_stmt;
end;

查看
show triggers;

删除
drop trigger [schema_name] trigger_name;#如果没有指定schema_name，默认为当前数据库*/

-- -------------------------------------------触发器 insert类型----------------------------------------------------

#根据需求，定义触发器。要求通过触发器记录tb_user表的数据变更日志，将变更日志插入到日志表use_logs中，包含增、删、改
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 tb_user for each row #为插入触发器，after表示在tb_user表插入之前就触发触发器，each row表示行级触发器
    #我们对tb_user表进行插入数据的时候就会触发
begin
    insert into user_logs(id,operation,operate_time,operate_id,operate_params) values
    (null,'insert',now(),new.id,concat('插入的数据内容为:id= ',new.id,',name= ',new.name,',phone=',new.phone,',email=',new.email,',profession=',new.profession));
    #new.id新插入数据的id，以此类推
    #now()是时间函数，显示当前时间
end;

-- 查看当前数据库有哪些触发器
show triggers;
# 显示当前数据库有哪些触发器，触发器监控的是哪张表，监控的是什么操作，触发器的逻辑是什么，什么时候触发

-- 删除触发器
drop trigger tb_user_insert_trigger;
-- 删除user_logs表
drop table if exists user_logs;

-- 验证。插入数据到tb_user表
insert into tb_user(id,name,phone,email,profession,age,gender,status,createtime)
values (25,'张三','18809091212','zhangsan@163.com','软件工程',23,'1','1',now());
#可以发现tb_user多了一条id为25的数据。并且user_logs表记录了我们做出操作的详细信息，也就是日志记录

-- -------------------------------------------触发器 update类型----------------------------------------------------

-- 创建的是修改数据触发器
create trigger tb_user_update_trigger #创建触发器
    after update on tb_user for each row #为修改触发器，after表示在tb_user表更新之前就触发触发器，each row表示行级触发器
    #我们对tb_user表进行更新数据的时候就会触发
begin
    insert into user_logs(id,operation,operate_time,operate_id,operate_params) values
    #要同时记录更新数据之前的数据和更新之后的数据
    (null,'update',now(),new.id,
    concat('更新之前的数据:id= ',old.id,',age= ',old.age,',phone=',old.phone,',email=',old.email,',profession=',old.profession,
           ' | 更新之后的数据:id= ',new.id,',age= ',new.age,',phone=',new.phone,',email=',new.email,',profession=',new.profession
    ));
end;

-- 查看当前数据库有哪些触发器
show triggers;

-- 删除触发器
drop trigger tb_user_update_trigger;
-- 删除user_logs表
drop table if exists user_logs;

-- 验证。更新tb_user表的数据
update tb_user set age = 30 where id = 23;
update tb_user set profession = '会计' where id <= 5;#由于创建的触发器是行级触发器，这里会修改5次表数据，所以触发词会被触发5次，生成5条日志

-- -------------------------------------------触发器 delete类型----------------------------------------------------

-- 创建的是删除数据触发器
create trigger tb_user_delete_trigger #创建触发器
    after delete on tb_user for each row #为删除触发器，after表示在tb_user表更新之前就触发触发器，each row表示行级触发器
    #我们对tb_user表进行删除数据的时候就会触发
begin
    insert into user_logs(id,operation,operate_time,operate_id,operate_params) values
    #要同时记录更新数据之前的数据和更新之后的数据
    (null,'delete',now(),old.id,#new是记录数据变更之后，我们都删除了数据所以是记录不到的，所以要把new改为old，表示记录的是数据变更之前的数据
    concat('删除之前的数据:id= ',old.id,',age= ',old.age,',phone=',old.phone,',email=',old.email,',profession=',old.profession));
    #没有删除之后的数据。因为都删除了，你怎么知道删除之后会是什么数据
end;

-- 查看当前数据库有哪些触发器
show triggers;

-- 删除触发器
drop trigger tb_user_delete_trigger;
-- 删除user_logs表
drop table if exists user_logs;

-- 验证。删除tb_user表的某条数据
delete from tb_user where id = 25;

