视图、触发器、存储过程、流程控制、事物

视图

视图是一张虚拟的表(只有表结构,没有表数据),但是它的修改会影响关联它的表
#语法:CREATE VIEW 视图名称 AS  SQL语句
create view teacher_view as select tid from teacher where tname='李平老师';
  mysql> show tables;
  +---------------+
  | Tables_in_crm |
  +---------------+
  | class |
  | course |
  | score |
  | student |
  | teacher |
  | teacher_view |  #看这里
  +---------------+

  mysql> desc teacher_view;  #有表结构
  +-------+---------+------+-----+---------+-------+
  | Field | Type | Null | Key | Default | Extra |
  +-------+---------+------+-----+---------+-------+
  | tid | int(11) | NO | | 0 | |
  +-------+---------+------+-----+---------+-------+
  1 row in set (0.04 sec)

  mysql> select * from teacher_view; #有表数据
  +-----+
  | tid |
  +-----+
  | 2 |
  +-----+
  1 row in set (0.00 sec)

注意:视图只有表结构,没有表数据,视图的好处是以后我们如果再需要查询或者使用上面的虚拟表,就可以直接使用这个视图了,sql的代码量也会省很多。但是弊端也很致命,看下面注意的内容。

#于是查询李平老师教授的课程名的sql可以改写为
mysql> select cname from course where teacher_id = (select tid from teacher_view);
+--------+
| cname  |
+--------+
| 物理   |
| 美术   |
+--------+
2 rows in set (0.00 sec)

#!!!注意注意注意:
#1. 使用视图以后就无需每次都重写子查询的sql,开发的时候是方便了很多,但是这么效率并不高,还不如我们写子查询的效率高

#2. 而且有一个致命的问题:视图是存放到数据库里的,如果我们程序中的sql过分依赖于数据库中存放的视图,那么意味着,一旦sql需要修改且涉及到视图的部分,则必须去数据库中进行修改,然后再到自己的应用程序里面将那个sql语句改一改,需要很多的修改工作,并而对视图的更改通常在一般中型及以上公司中数据库有专门的DBA负责,你要想完成修改,必须付出大量的沟通成本DBA可能才会帮你完成修改,极其地不方便
这么多的弊端,为什么mysql还要提供这个东西呢,有一点是因为mysql想把所有数据处理的工作全部接手过来,但其实还有其他的原因,等我们讲完存储过程在和大家说吧。
#3 并且注意:视图一般都是用于查询,尽量不要修改(插入、删除等)视图中的数据,虽然有时候可以修改成功,但是尽量不要这样做,因为这个视图可能是多个表联合起来生成的一个结果,如果你修改它,可能会造成很多表里面的数据都跟着被修改了

 

 

 触发器

  使用触发器可以定制用户对某一张表的数据进行【增、删、改】操作时前后的行为
(没有查询),在进行增删改操作的时候,触发的某个操作,称为触发器,也就是增删改的行为触发另外的一种行为,
触发的行为无非就是sql语句的事情,及自动运行另外一段sql语句
注意:名字的设置要见名知义

 

示例
delimiter // #将结束符; 改为// create trigger t_name before(after) insert(update\delete) on 表名 for each row begin #一直到end,这里面的代码就是触发器要做的sql事情, select * from xx; ... end // delimiter ;

 

事物(原子性,持久性,一致性,隔离性)  

原子性:要么全部成功,要么全部失败
一致性: 数据的一致
隔离性:别人看不到事物里面的执行结果(conmilit提交之前),只能看到磁盘上的数据
持久性:改完就没法再回滚回去,只能手动修改

 

  事务用于将某些操作的多个SQL作为原子性操作,也就是这些sql语句要么同时成功,要么都不成功,一旦有某一个出现错误,
即可回滚到原来的状态,从而保证数据库数据完整性。   简单来说:我给一个姑娘转账,姑娘那儿收到了200,你的账户上扣了200,这两个操作是不是两个sql语句,这两个sql语句是你的应用程序发给mysql服务端的,并且这两个sql语句都要一起执行,不然数据就错了,
你想想是不是。并且如果你通过应用程序发送这两条sql的时候,由于网络问题,你只发送了一个sql过来,那只有一个账户改了数据,另外一个没改,那数据是不是就出错了啊。这就是事务要完成的事情。

 

start transaction;
一堆sql语句
如果失败
declare exit handler fro sqlexception
begin
rollback;  #回滚
end

commit;  #提交

 

存储过程        (可以有参数[in(传入参数的) , out(返回值) , inout(既可传入又可以返回值)])

类似于python里的 函数时的操作(创建,调用都有很相似)

#创建存储过程
delimiter //
create procedure p1(in n1 int,out n2 int, inout n3 int)  #out,inout 传参时要给个变量名,mysql里面变量要以@开头
BEGIN
    select * from blog;
    INSERT into blog(name,sub_time) values("xxx",now());
END //
delimiter ;

#调用存储过程,先设置变量set @...
set @res=1;
set @res2=2;
call p1(1,@res,@res2);#类似于MySQL的函数,但不是函数,MySQL的函数(count()\max()\min()等等)都是放在sql语句里面用的,不能单独的使用,存储过程是可以直接调用的 call 名字+括号;
select @res,@res2;#(查看变量值) #类似于MySQL的函数,但不是函数,MySQL的函数(count()\max()\min()等等)都是放在sql语句里面用的,不能单独的使用,存储过程是可以直接调用的  call 名字+括号;
#MySQL的视图啊触发器啊if判断啊等等都能在存储过程里面写,这是一大堆的sql的集合体,都可以综合到这里面
#python中基于pymysql调用
  cursor.callproc('p1',(1,2,3)) #底层会将输入的数据转换成 @_p1_1,@_p1_2,@_p1_3   print(cursor.fetchall())

流程控制

if条件语句
delimiter //
CREATE PROCEDURE proc_if ()
BEGIN
    
    declare i int default 0;
    if i = 1 THEN
        SELECT 1;
    ELSEIF i = 2 THEN
        SELECT 2;
    ELSE
        SELECT 7;
    END IF;

END //
delimiter ;

 

循环语句
delimiter //
CREATE PROCEDURE proc_while ()
BEGIN

    DECLARE num INT ;
    SET num = 0 ;
    WHILE num < 10 DO
        SELECT
            num ;
        SET num = num + 1 ;
    END WHILE ;

END //
delimiter ;

 

posted @ 2019-01-22 21:51  Tank-Li  阅读(219)  评论(0编辑  收藏  举报