zoukankan      html  css  js  c++  java
  • 12 MySQL--内置功能介绍

    mysql内置功能:
        1.视图
        2.触发器
        3.存储过程
        4.事务
        5.函数
       6.函数流程控制

    一、视图

    介绍:
            视图是一个虚拟表(非真实存在),其本质是【根据SQL语句获取动态的数据集,并为其命名】,
            用户使用时只需使用【名称】即可获取结果集,可以将该结果集当做表来使用。
            使用视图我们可以把查询过程中的临时表摘出来,用视图去实现,
            这样以后再想操作该临时表的数据时就无需重写复杂的sql了,直接去视图中查找即可,
            但视图有明显地效率问题,并且视图是存放在数据库中的,
            如果我们程序中使用的sql过分依赖数据库中的视图,即强耦合,那就意味着扩展sql极为不便,
            因此并不推荐使用;
            
            把sql语句查询出来得虚拟表保存下来;
            视图:硬盘只存结构,不存数据,因为数据本身来源于其他表
                 减少代码冗余,但是不建议使用,数据库扩展,就影响视图,就得修改视图。
    
            视图得目的:取代复杂得sql语句,针对单表做视图,没有意义;
                       视图是用来查得,多张表,视图数据不应该被改,
                       视图是方便来查得,不是用来改得!
    #两张有关系的表
    mysql> select * from course;
    +-----+--------+------------+
    | cid | cname  | teacher_id |
    +-----+--------+------------+
    |   1 | 生物   |          1 |
    |   2 | 物理   |          2 |
    |   3 | 体育   |          3 |
    |   4 | 美术   |          2 |
    +-----+--------+------------+
    rows in set (0.00 sec)
    
    mysql> select * from teacher;
    +-----+-----------------+
    | tid | tname           |
    +-----+-----------------+
    |   1 | 张磊老师        |
    |   2 | 李平老师        |
    |   3 | 刘海燕老师      |
    |   4 | 朱云海老师      |
    |   5 | 李杰老师        |
    +-----+-----------------+
    rows in set (0.00 sec)
    
    #查询李平老师教授的课程名
    mysql> select cname from course where teacher_id = (select tid from teacher where tname='李平老师');
    +--------+
    | cname  |
    +--------+
    | 物理   |
    | 美术   |
    +--------+
    rows in set (0.00 sec)
    
    #子查询出临时表,作为teacher_id等判断依据
    select tid from teacher where tname='李平老师'
    
    临时表应用举例

    1、创建视图

    #语法:CREATE VIEW 视图名称 AS  SQL语句
    create view teacher_view as select tid from teacher where tname='李平老师';
    
    #于是查询李平老师教授的课程名的sql可以改写为
    mysql> select cname from course where teacher_id = (select tid from teacher_view);
    +--------+
    | cname  |
    +--------+
    | 物理   |
    | 美术   |
    +--------+
    rows in set (0.00 sec)
    
    #!!!注意注意注意:
    #1. 使用视图以后就无需每次都重写子查询的sql,但是这么效率并不高,还不如我们写子查询的效率高
    
    #2. 而且有一个致命的问题:视图是存放到数据库里的,如果我们程序中的sql过分依赖于数据库中存放的视图,
    那么意味着,一旦sql需要修改且涉及到视图的部分,则必须去数据库中进行修改,而通常在公司中数据库有专门的DBA负责,
    你要想完成修改,必须付出大量的沟通成本DBA可能才会帮你完成修改,极其地不方便

    2、使用视图

    #修改视图,原始表也跟着改
    mysql> select * from course;
    +-----+--------+------------+
    | cid | cname  | teacher_id |
    +-----+--------+------------+
    |   1 | 生物   |          1 |
    |   2 | 物理   |          2 |
    |   3 | 体育   |          3 |
    |   4 | 美术   |          2 |
    +-----+--------+------------+
    rows in set (0.00 sec)
    
    mysql> create view course_view as select * from course; #创建表course的视图
    Query OK, 0 rows affected (0.52 sec)
    
    mysql> select * from course_view;
    +-----+--------+------------+
    | cid | cname  | teacher_id |
    +-----+--------+------------+
    |   1 | 生物   |          1 |
    |   2 | 物理   |          2 |
    |   3 | 体育   |          3 |
    |   4 | 美术   |          2 |
    +-----+--------+------------+
    rows in set (0.00 sec)
    
    mysql> update course_view set cname='xxx'; #更新视图中的数据
    Query OK, 4 rows affected (0.04 sec)
    Rows matched: 4  Changed: 4  Warnings: 0
    
    mysql> insert into course_view values(5,'yyy',2); #往视图中插入数据
    Query OK, 1 row affected (0.03 sec)
    
    mysql> select * from course; #发现原始表的记录也跟着修改了
    +-----+-------+------------+
    | cid | cname | teacher_id |
    +-----+-------+------------+
    |   1 | xxx   |          1 |
    |   2 | xxx   |          2 |
    |   3 | xxx   |          3 |
    |   4 | xxx   |          2 |
    |   5 | yyy   |          2 |
    +-----+-------+------------+
    rows in set (0.00 sec)

    3、修改视图

    语法:ALTER VIEW 视图名称 AS SQL语句
    mysql> alter view teacher_view as select * from course where cid>3;
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> select * from teacher_view;
    +-----+-------+------------+
    | cid | cname | teacher_id |
    +-----+-------+------------+
    |   4 | xxx   |          2 |
    |   5 | yyy   |          2 |
    +-----+-------+------------+
    rows in set (0.00 sec)

    4、删除视图

    语法:DROP VIEW 视图名称
    
    DROP VIEW teacher_view

    二、 触发器

    使用触发器可以定制用户对表进行【增、删、改】操作时前后的行为,注意:没有查询

    增    before insert ;  after insert

    1、创建触发器

    trigger 英 /'trɪgə/  /'trɪɡɚ/   vt 触发、引发

    create trigger tri_before_insert_tb1 before insert on tb1 for each row # row 行

    #
    插入前 触发 CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW BEGIN ... END # 插入后 CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW BEGIN ... END # 删除前 CREATE TRIGGER tri_before_delete_tb1 BEFORE DELETE ON tb1 FOR EACH ROW BEGIN ... END # 删除后 CREATE TRIGGER tri_after_delete_tb1 AFTER DELETE ON tb1 FOR EACH ROW BEGIN ... END # 更新前 CREATE TRIGGER tri_before_update_tb1 BEFORE UPDATE ON tb1 FOR EACH ROW BEGIN ... END # 更新后 CREATE TRIGGER tri_after_update_tb1 AFTER UPDATE ON tb1 FOR EACH ROW BEGIN ... END

    delimiter英 /dɪ'lɪmɪtə/ , /dɪ'lɪmɪtɚ/ 定界符,分隔符

    默认情况下,mysql解释器一遇到分号(;),它就要自动执行。 
    不会等到用户把这些语句全部输入完之后,再执行整段语句。 
    
    而自定义函数和存储过程的SQL语句有好多行,且语句中包含有分号,
    为了保证整段语句的整体执行,就要使用delimiter,更改mysql的默认结束符。 

    先将分隔符设置为 //, 
    
    
    直到遇到下一个 //,才整体执行语句。
    
    
    执行完后,最后一行, delimiter ; 将mysql的分隔符重新设置为分号;
    
    
    如果不修改的话,本次会话中的所有分隔符都以// 为准。
     

    先准备表,在创建触发器,

    #准备表
    CREATE TABLE cmd (
        id INT PRIMARY KEY auto_increment,
        USER CHAR (32),
        priv CHAR (10),
        cmd CHAR (64),
        sub_time datetime, #提交时间
        success enum ('yes', 'no') #0代表执行失败
    );
    
    CREATE TABLE errlog (
        id INT PRIMARY KEY auto_increment,
        err_cmd CHAR (64),
        err_time datetime
    );
    
    #创建触发器
    delimiter //
    CREATE TRIGGER tri_after_insert_cmd AFTER INSERT ON cmd FOR EACH ROW
    BEGIN
        IF NEW.success = 'no' THEN #等值判断只有一个等号 NEW是新增加进来的数据        修改old是老记录
                INSERT INTO errlog(err_cmd, err_time) VALUES(NEW.cmd, NEW.sub_time) ; #必须加分号
          END IF ; #必须加分号
    END//
    delimiter ;
    
    
    #往表cmd中插入记录,触发触发器,根据IF的条件决定是否插入错误日志
    INSERT INTO cmd (
        USER,
        priv,
        cmd,
        sub_time,
        success
    )
    VALUES
        ('egon','0755','ls -l /etc',NOW(),'yes'),
        ('egon','0755','cat /etc/passwd',NOW(),'no'),
        ('egon','0755','useradd xxx',NOW(),'no'),
        ('egon','0755','ps aux',NOW(),'yes');
    
    
    #查询错误日志,发现有两条
    mysql> select * from errlog;
    +----+-----------------+---------------------+
    | id | err_cmd         | err_time            |
    +----+-----------------+---------------------+
    |  1 | cat /etc/passwd | 2017-09-14 22:18:48 |
    |  2 | useradd xxx     | 2017-09-14 22:18:48 |
    +----+-----------------+---------------------+
    rows in set (0.00 sec)
    
    插入后触发触发器

    特别的:NEW表示即将插入的数据行,OLD表示即将删除的数据行。

    应用开发程序员 和 数据库程序员是两个部分,所以实际上部分沟通问题,所以实际开发时程序员自己设计触发器,

    二 使用触发器

    触发器无法由用户直接调用,而知由于对表的【增/删/改】操作被动引发的。

    三 删除触发器

    drop trigger tri_after_insert_cmd;

     

  • 相关阅读:
    select、poll和epoll
    Linux 常用命令之文件和目录
    SmartPlant Review 帮助文档机翻做培训手册
    SmartPlant Foundation 基础教程 3.4 菜单栏
    SmartPlant Foundation 基础教程 3.3 标题栏
    SmartPlant Foundation 基础教程 3.2 界面布局
    SmartPlant Foundation 基础教程 3.1 DTC登陆界面
    SmartPlant Foundation 基础教程 1.4 SPF架构
    SmartPlant Foundation 基础教程 1.3 SPF其他功能
    SmartPlant Foundation 基础教程 1.2 SPF集成设计功能
  • 原文地址:https://www.cnblogs.com/foremostxl/p/9770829.html
Copyright © 2011-2022 走看看