美文网首页
04MySQL的视图、存储过程和触发器

04MySQL的视图、存储过程和触发器

作者: AdRainty | 来源:发表于2022-02-06 18:49 被阅读0次

    一、MySQL的视图

    视图(view)是一个虚拟表,非真实存在,其本质是根据SQL语句获取动态的数据集,并为其命名,用户使用时只需使用视图名称即可获取结果集,并可以将其当作表来使用。数据库中只存放了视图的定义,而并没有存放视图中的数据。这些数据存放在原来的表中。使用视图查询数据时,数据库系统会从原来的表中取出对应的数据。因此,视图中的数据是依赖于原来的表中的数据的。一旦表中的数据发生改变,显示在视图中的数据也会发生改变。

    视图的作用有

    • 简化代码,可以把重复使用的查询封装成视图重复使用,同时可以使复杂的查询易于理解和使用。
    • 安全原因,如果一张表中有很多数据,很多信息不希望让所有人看到,此时可以使用视图

    1.1 视图的创建

    创建视图的语法为

    create [or replace] [algorithm = {undefined | merge | temptable}]
    view view_name [(column_list)]
    as select_statement
    [with [cascaded | local] check option]
    
    /*
    参数说明:
    (1)algorithm:可选项,表示视图选择的算法。
    (2)view_name :表示要创建的视图名称。
    (3)column_list:可选项,指定视图中各个属性的名词,默认情况下与SELECT语句中的查询的属性相同。
    (4)select_statement:表示一个完整的查询语句,将查询记录导入视图中。
    (5)[with [cascaded | local] check option]:可选项,表示更新视图时要保证在该视图的权限范围之内。
    */
    

    1.2 修改视图

    修改视图是指修改数据库中已存在的表的定义。当基本表的某些字段发生改变时,可以通过修改视图来保持视图和基本表之间一致。MySQL中通过CREATE OR REPLACE VIEW语句和ALTER VIEW语句来修改视图。

    alter view 视图名 as select语句
    

    1.3 更新视图

    某些视图是可更新的。也就是说,可以在UPDATE、DELETE或INSERT等语句中使用它们,以更新基表的内容。对于可更新的视图,在视图中的行和基表中的行之间必须具有一对一的关系。如果视图包含下述结构中的任何一种,那么它就是不可更新的:

    • 聚合函数(SUM(), MIN(), MAX(), COUNT()等)
    • DISTINCT
    • GROUP BY
    • HAVING
    • UNION或UNION ALL
    • 位于选择列表中的子查询
    • JOIN
    • FROM子句中的不可更新视图
    • WHERE子句中的子查询,引用FROM子句中的表。
    • 仅引用文字值(在该情况下,没有要更新的基本表)

    视图中虽然可以更新数据,但是有很多的限制。一般情况下,最好将视图作为查询数据的虚拟表,而不要通过视图更新数据。因为,使用视图更新数据时,如果没有全面考虑在视图中更新数据的限制,就可能会造成数据更新失败。

    1.4 其他操作

    • 重命名视图
    -- rename table 视图名 to 新视图名; 
    rename table view1_emp to my_view1
    
    • 删除视图
    -- drop view 视图名[,视图名…];
    drop view if exists view_student;
    

    删除视图时,只能删除视图的定义,不会删除数据。

    二、MySQL的存储过程

    简单的说,存储过程就是一组SQL语句集,功能强大,可以实现一些比较复杂的逻辑功能,类似于JAVA语言中的方法;存储过就是数据库 SQL 语言层面的代码封装与重用。

    存储过程的特性:

    • 有输入输出参数,可以声明变量,有if/else, case,while等控制语句,通过编写存储过程,可以实现复杂的逻辑功能;
    • 函数的普遍特性:模块化,封装,代码复用;
    • 速度快,只有首次执行需经过编译和优化步骤,后续被调用可以直接执行,省去以上步骤;

    2.1 存储过程的使用

    其格式为

    delimiter 自定义结束符号
    create procedure 储存名([ in ,out ,inout ] 参数名 数据类形...)
    begin
      sql语句
    end 自定义的结束符合
    delimiter ;
    
    -- 调用存储过程
    call 储存名(); 
    

    2.2 变量定义

    2.2.1 局部变量

    用户自定义,在begin/end块中有效

    -- 声明变量 
    -- declare var_name type [default var_value]; 
    declare nickname varchar(32);
    -- 变量赋值
    set nickname = ‘zhangsan’;  
    

    MySQL 中还可以使用 SELECT..INTO 语句为变量赋值。其基本语法如下:

    select col_name [...] into var_name[,...] 
    from table_name wehre condition 
    /*
    其中:
    col_name 参数表示查询的字段名称;
    var_name 参数是变量的名称;
    table_name 参数指表的名称;
    condition 参数指查询条件。
    注意:当将查询结果赋值给变量时,该查询语句的返回结果只能是单行单列。
    */
    

    2.2.2 用户变量

    用户自定义,当前会话(连接)有效。类比java的成员变量 不需要提前声明,使用即声明

    -- 语法: 
    @var_name
    

    例如

    delimiter $$
    create procedure proc04()
    begin
        set @var_name01  = 'ZS';
    end $$
    delimiter;
    call proc04() ;
    

    2.2.3 系统变量

    系统变量又分为全局变量与会话变量

    • 全局变量在MYSQL启动的时候由服务器自动将它们初始化为默认值,这些默认值可以通过更改my.ini这个文件来更改。
    • 会话变量在每次建立一个新的连接的时候,由MYSQL来初始化。MYSQL会将当前所有全局变量的值复制一份。来做为会话变量。

    也就是说,如果在建立会话以后,没有手动更改过会话变量与全局变量的值,那所有这些变量的值都是一样的。全局变量与会话变量的区别就在于,对全局变量的修改会影响到整个服务器,但是对会话变量的修改,只会影响到当前的会话(也就是当前的数据库连接)。有些系统变量的值是可以利用语句来动态进行更改的,但是有些系统变量的值却是只读的,对于那些可以更改的系统变量,我们可以利用set语句进行更改。

    全局变量的语法:

    @@global.var_name
    
    -- 查看全局变量 
    show global variables; 
    -- 查看某全局变量 
    select @@global.auto_increment_increment; 
    -- 修改全局变量的值 
    set global sort_buffer_size = 40000; 
    set @@global.sort_buffer_size = 40000;
    

    会话变量的语法

    @@session.var_name
    
    -- 查看会话变量
    show session variables;
    -- 查看某会话变量 
    select @@session.auto_increment_increment;
    -- 修改会话变量的值
    set session sort_buffer_size = 50000; 
    set @@session.sort_buffer_size = 50000 ;
    

    2.3 存储过程传参

    • in 表示传入的参数, 可以传入数值或者变量,即使传入变量,并不会更改变量的值,可以内部更改,仅仅作用在函数范围内。

    • out 表示从存储过程内部传值给调用者

    • inout 表示从外部传入的参数经过修改后可以返回的变量,既可以使用传入变量的值也可以修改变量的值(即使函数执行完)

    2.4 流程控制

    2.4.1 判断

    IF语句包含多个条件判断,根据结果为TRUE、FALSE执行语句,与编程语言中的if、else if、else语法类似,其语法格式如下

    -- 语法
    if search_condition_1 then statement_list_1
        [elseif search_condition_2 then statement_list_2] ...
        [else statement_list_n]
    end if
    

    CASE是另一个条件判断的语句,类似于编程语言中的switch语法

    -- 语法一(类比java的switch):
    case case_value
        when when_value then statement_list
        [when when_value then statement_list] ...
        [else statement_list]
    end case
    -- 语法二:
    case
        when search_condition then statement_list
        [when search_condition then statement_list] ...
        [else statement_list]
    end case
    

    2.4.2 循环

    循环是一段在程序中只出现一次,但可能会连续运行多次的代码,循环中的代码会运行特定的次数,或者是运行到特定条件成立时结束循环

    循环的类别包括

    • while
    • repeat
    • loop
    -- 类似于while
    [标签:] while 循环条件 do
        循环体;
    end while[标签];
    

    循环控制包括

    • leave 类似于 break,跳出,结束当前所在的循环
    • iterate类似于 continue,继续,结束本次循环,继续下一次
    -- 类似于do while
    [标签:] repeat 
     循环体;
    until 条件表达式
    end repeat [标签];
    
    [标签:] loop
      循环体;
      if 条件表达式 then 
         leave [标签]; 
      end if;
    end loop;
    

    2.5 游标

    游标(cursor)是用来存储查询结果集的数据类型 , 在存储过程和函数中可以使用光标对结果集进行循环的处理。光标的使用包括光标的声明、OPEN、FETCH 和 CLOSE.

    -- 声明语法
    declare cursor_name cursor for select_statement
    -- 打开语法
    open cursor_name
    -- 取值语法
    fetch cursor_name into var_name [, var_name] ...
    -- 关闭语法
    close cursor_name
    

    2.6 异常处理

    MySql存储过程也提供了对异常处理的功能:通过定义HANDLER来完成异常声明的实现.

    官方文档:https://dev.mysql.com/doc/refman/5.7/en/declare-handler.html

    DECLARE handler_action HANDLER
        FOR condition_value [, condition_value] ...
        statement
    
    /*
    handler_action: {
        CONTINUE    -- 继续执行
      | EXIT        -- 退出程序
      | UNDO        -- 不支持,暂时不使用
    }
     
    condition_value: {
        mysql_error_code        -- MySQL的条件码
      | condition_name          -- MySQL的条件名
      | SQLWARNING              
      | NOT FOUND               
      | SQLEXCEPTION    
    */
    

    在语法中,变量声明、游标声明、handler声明是必须按照先后顺序书写的,否则创建存储过程出错。

    三、MySQL的存储函数

    MySQL存储函数(自定义函数),函数一般用于计算和返回一个值,可以将经常需要使用的计算或功能写成一个函数。存储函数和存储过程一样,都是在数据库中定义一些 SQL 语句的集合。

    存储函数与存储过程的区别在于

    • 存储函数有且只有一个返回值,而存储过程可以有多个返回值,也可以没有返回值。

    • 存储函数只能有输入参数,而且不能带in, 而存储过程可以有多个in,out,inout参数。

    • 存储过程中的语句功能更强大,存储过程可以实现很复杂的业务逻辑,而函数有很多限制,如不能在函数中使用insert,update,delete,create等语句;

    • 存储函数只完成查询的工作,可接受输入参数并返回一个结果,也就是函数实现的功能针对性比较强。

    • 存储过程可以调用存储函数。但函数不能调用存储过程。

    • 存储过程一般是作为一个独立的部分来执行(call调用)。而函数可以作为查询语句的一个部分来调用.

    在MySQL中,创建存储函数使用create function关键字,其基本形式如下:

    create function func_name ([param_name type[,...]])
    returns type
    [characteristic ...] 
    begin
        routine_body
    end;
    
    /*
    func_name :存储函数的名称。
    param_name type:可选项,指定存储函数的参数。type参数用于指定存储函数的参数类型,该类型可以是MySQL数据库中所有支持的类型。
    RETURNS type:指定返回值的类型。
    characteristic:可选项,指定存储函数的特性。
    routine_body:SQL代码内容。
    */
    

    四、MySQL的触发器

    触发器,就是一种特殊的存储过程。触发器和存储过程一样是一个能够完成特定功能、存储在数据库服务器上的SQL片段,但是触发器无需调用,当对数据库表中的数据执行DML操作时自动触发这个SQL片段的执行,无需手动条用。在MySQL中,只有执行insert,delete,update操作时才能触发触发器的执行,触发器的这种特性可以协助应用在数据库端确保数据的完整性 , 日志记录 , 数据校验等操作 。可以使用别名 OLD 和 NEW 来引用触发器中发生变化的记录内容,这与其他的数据库是相似的。现在触发器还只支持行级触发,不支持语句级触发。

    4.1 创建触发器

    • 创建只有一个执行语句的触发器
    create trigger 触发器名 before|after 触发事件
    on 表名 for each row 
    执行语句;
    
    • 创建有多个执行语句的触发器
    create trigger 触发器名 before|after  触发事件 
    on 表名 for each row
    begin
         执行语句列表
    end;
    

    4.2 NEW与OLD

    MySQL 中定义了 NEW 和 OLD,用来表示触发器的所在表中,触发了触发器的那一行数据,来引用触发器中发生变化的记录内容,具体地:

    触发器类型 触发器类型NEW OLD的使用
    INSERT 型触发器 NEW 表示将要或者已经新增的数据
    UPDATE 型触发器 OLD 表示修改之前的数据 , NEW 表示将要或已经修改后的数据
    DELETE 型触发器 OLD 表示将要或者已经删除的数据

    4.3 查看和删除触发器

    • 查看触发器
    show triggers;
    
    • 删除触发器
    -- drop trigger [if exists] trigger_name 
    drop trigger if exists trigger_test1;
    
    1. MYSQL中触发器中不能对本表进行 insert ,update ,delete 操作,以免递归循环触发

    2. 尽量少使用触发器,假设触发器触发每次执行1s,insert table 500条数据,那么就需要触发500次触发器,光是触发器执行的时间就花费了500s,而insert 500条数据一共是1s,那么这个insert的效率就非常低了。

    3. 触发器是针对每一行的;对增删改非常频繁的表上切记不要使用触发器,因为它会非常消耗资源。

    相关文章

      网友评论

          本文标题:04MySQL的视图、存储过程和触发器

          本文链接:https://www.haomeiwen.com/subject/iyqekrtx.html