美文网首页
47-视图,触发器,事务,存储过程,函数和流程控制

47-视图,触发器,事务,存储过程,函数和流程控制

作者: 天行_b6d0 | 来源:发表于2020-09-14 21:30 被阅读0次

    一、视图

    视图是一个虚拟表(非真实存在),其本质是【根据SQL语句获取动态的数据集,并为其命名】,用户使用时只需使用【名称】即可获取结果集,可以将该结果集当做表来使用。

    使用视图我们可以把查询过程中的临时表摘出来,用视图去实现,这样以后再想操作该临时表的数据时就无需重写复杂的sql了,直接去视图中查找即可,但视图有明显地效率问题,并且视图是存放在数据库中的,如果我们程序中使用的sql过分依赖数据库中的视图,即强耦合,那就意味着扩展sql极为不便,因此并不推荐使用

    创建视图:语法:CREATE VIEW 视图名称 AS SQL语句

    修改视图:语法:ALTER VIEW 视图名称 AS SQL语句

    删除视图:语法:DROP VIEW 视图名称

    二、触发器

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

    1、创建触发器

    其中,NEW表示即将插入的数据行,OLD表示即将删除的数据行。

    插入前
    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

    2、删除触发器

    drop trigger 触发器名称

    三、事务

    1、什么是事务:

    数据库事务是指作为单个逻辑工作单元执行的一系列操作(SQL语句)。这些操作要么全部执行,要么全部不执行。

    2、为什么需要事务

    经典的银行转账行为,A账户转给B账户10元,数据库操作需要两步,第一步A账户减10元,第二步B账户加10元,如果没有事务并且在两步中间发生异常,就会导致A的账户少了10元,但B的账户没有变化,如果不能保证这两步操作统一,银行的转账业务也没法进行展开了。
    事务管理是每个数据库(oracle、mysql、db等)都必须实现的。

    3、事务特性(4种):
    • 原子性 (atomicity):强调事务的不可分割.
    • 一致性 (consistency):事务的执行的前后数据的完整性保持一致.
    • 隔离性 (isolation):一个事务执行的过程中,不应该受到其他事务的干扰
    • 持久性(durability) :事务一旦结束,数据就持久到数据库
    4、事务运行模式(3种)
    • 自动提交事务:默认事务管理模式。如果一个语句成功地完成,则提交该语句;如果遇到错误,则回滚该语句。
    • 显式事务:以BEGIN TRANSACTION显式开始,以COMMIT或ROLLBACK显式结束。
    • 隐性事务:当连接以此模式进行操作时,sql将在提交或回滚当前事务后自动启动新事务。无须描述事务的开始,只需提交或回滚每个事务。它生成连续的事务链。
    start transaction;  # 开启一个事务
    sql语句1;
    sql语句2;
    sql语句3;
    rollback;  # 回滚
    commit;  # 真正将修改提交到数据库中
    

    四、存储过程

    存储过程包含了一系列可执行的sql语句,存储过程存放于MySQL中,通过调用它的名字可以执行其内部的一堆sql。

    程序和数据库结合使用的三种方式:
    • 方式一:
      MySQL:存储过程
      程序:调用存储过程

    • 方式二:
      MySQL:
      程序:纯SQL语句

    • 方式三:
      MySQL:
      程序:类和对象,即ORM(本质还是纯SQL语句)

    创建无参存储过程
    delimiter $$
    create procedure p1()
    begin
        select * from emp;
    end $$
    
    delimiter ;
    
    call p1();
    
    创建有参存储过程
    delimiter $$
    create procedure p2(
        in n int,
        out res int
    )
    begin
        select * from emp where id > n;
        set res=1;
    end $$
    
    delimiter ;
    
    set @x=1111;
    call p2(3,@x);
    
    应用程序执行存储过程:
    import pymysql  # pip3 install pymysql
    
    conn = pymysql.connect(host="127.0.0.1", port=3306, user="root", password="123", db="db4", charset="utf8mb4")
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    
    
    cursor.callproc('p2',(3,0))  # @_p2_0=3,@_p2_1=0
    '''
    set @_p2_0=3
    set @_p2_1=0
    
    call p2(@_p2_0,@_p2_1);
    
    '''
    
    print(cursor.fetchall())
    
    cursor.execute("select @_p2_1;")
    print(cursor.fetchall())
    
    cursor.execute("select @_p2_0;")
    print(cursor.fetchall())
    
    cursor.close()
    conn.close()
    

    五、函数

    一、数学函数
        ROUND(x,y)
            返回参数x的四舍五入的有y位小数的值
            
        RAND()
            返回0到1内的随机值,可以通过提供一个参数(种子)使RAND()随机数生成器生成一个指定的值。
    
    二、聚合函数(常用于GROUP BY从句的SELECT查询中)
        AVG(col)返回指定列的平均值
        COUNT(col)返回指定列中非NULL值的个数
        MIN(col)返回指定列的最小值
        MAX(col)返回指定列的最大值
        SUM(col)返回指定列的所有值之和
        GROUP_CONCAT(col) 返回由属于一组的列值连接组合而成的结果    
        
    三、字符串函数
    
        CHAR_LENGTH(str)
            返回值为字符串str 的长度,长度的单位为字符。一个多字节字符算作一个单字符。
        CONCAT(str1,str2,...)
            字符串拼接
            如有任何一个参数为NULL ,则返回值为 NULL。
        CONCAT_WS(separator,str1,str2,...)
            字符串拼接(自定义连接符)
            CONCAT_WS()不会忽略任何空字符串。 (然而会忽略所有的 NULL)。
    
        CONV(N,from_base,to_base)
            进制转换
            例如:
                SELECT CONV('a',16,2); 表示将 a 由16进制转换为2进制字符串表示
    
        FORMAT(X,D)
            将数字X 的格式写为'#,###,###.##',以四舍五入的方式保留小数点后 D 位, 并将结果以字符串的形式返回。若  D 为 0, 则返回结果不带有小数点,或不含小数部分。
            例如:
                SELECT FORMAT(12332.1,4); 结果为: '12,332.1000'
        INSERT(str,pos,len,newstr)
            在str的指定位置插入字符串
                pos:要替换位置其实位置
                len:替换的长度
                newstr:新字符串
            特别的:
                如果pos超过原字符串长度,则返回原字符串
                如果len超过原字符串长度,则由新字符串完全替换
        INSTR(str,substr)
            返回字符串 str 中子字符串的第一个出现位置。
    
        LEFT(str,len)
            返回字符串str 从开始的len位置的子序列字符。
    
        LOWER(str)
            变小写
    
        UPPER(str)
            变大写
       
        REVERSE(str)
            返回字符串 str ,顺序和字符顺序相反。
            
        SUBSTRING(str,pos) , SUBSTRING(str FROM pos) SUBSTRING(str,pos,len) , SUBSTRING(str FROM pos FOR len)
            不带有len 参数的格式从字符串str返回一个子字符串,起始于位置 pos。带有len参数的格式从字符串str返回一个长度同len字符相同的子字符串,起始于位置 pos。 使用 FROM的格式为标准 SQL 语法。也可能对pos使用一个负值。假若这样,则子字符串的位置起始于字符串结尾的pos 字符,而不是字符串的开头位置。在以下格式的函数中可以对pos 使用一个负值。
    
            mysql> SELECT SUBSTRING('Quadratically',5);
                -> 'ratically'
    
            mysql> SELECT SUBSTRING('foobarbar' FROM 4);
                -> 'barbar'
    
            mysql> SELECT SUBSTRING('Quadratically',5,6);
                -> 'ratica'
    
            mysql> SELECT SUBSTRING('Sakila', -3);
                -> 'ila'
    
            mysql> SELECT SUBSTRING('Sakila', -5, 3);
                -> 'aki'
    
            mysql> SELECT SUBSTRING('Sakila' FROM -4 FOR 2);
                -> 'ki'
                
    四、日期和时间函数
        CURDATE()或CURRENT_DATE() 返回当前的日期
        CURTIME()或CURRENT_TIME() 返回当前的时间
        DAYOFWEEK(date)   返回date所代表的一星期中的第几天(1~7)
        DAYOFMONTH(date)  返回date是一个月的第几天(1~31)
        DAYOFYEAR(date)   返回date是一年的第几天(1~366)
        DAYNAME(date)   返回date的星期名,如:SELECT DAYNAME(CURRENT_DATE);
        FROM_UNIXTIME(ts,fmt)  根据指定的fmt格式,格式化UNIX时间戳ts
        HOUR(time)   返回time的小时值(0~23)
        MINUTE(time)   返回time的分钟值(0~59)
        MONTH(date)   返回date的月份值(1~12)
        MONTHNAME(date)   返回date的月份名,如:SELECT MONTHNAME(CURRENT_DATE);
        NOW()    返回当前的日期和时间
        QUARTER(date)   返回date在一年中的季度(1~4),如SELECT QUARTER(CURRENT_DATE);
        WEEK(date)   返回日期date为一年中第几周(0~53)
        YEAR(date)   返回日期date的年份(1000~9999)
        
        重点:
        DATE_FORMAT(date,format) 根据format字符串格式化date值
    
           mysql> SELECT DATE_FORMAT('2009-10-04 22:23:00', '%W %M %Y');
            -> 'Sunday October 2009'
           mysql> SELECT DATE_FORMAT('2007-10-04 22:23:00', '%H:%i:%s');
            -> '22:23:00'
           mysql> SELECT DATE_FORMAT('1900-10-04 22:23:00',
            ->                 '%D %y %a %d %m %b %j');
            -> '4th 00 Thu 04 10 Oct 277'
           mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00',
            ->                 '%H %k %I %r %T %S %w');
            -> '22 22 10 10:23:00 PM 22:23:00 00 6'
           mysql> SELECT DATE_FORMAT('1999-01-01', '%X %V');
            -> '1998 52'
           mysql> SELECT DATE_FORMAT('2006-06-00', '%d');
            -> '00'
            
    五、加密函数
        MD5()    
            计算字符串str的MD5校验和
        PASSWORD(str)   
            返回字符串str的加密版本,这个加密过程是不可逆转的,和UNIX密码加密过程使用不同的算法。
            
    六、控制流函数            
        CASE WHEN[test1] THEN [result1]...ELSE [default] END
            如果testN是真,则返回resultN,否则返回default
        CASE [test] WHEN[val1] THEN [result]...ELSE [default]END  
            如果test和valN相等,则返回resultN,否则返回default
    
        IF(test,t,f)   
            如果test是真,返回t;否则返回f
    
        IFNULL(arg1,arg2) 
            如果arg1不是空,返回arg1,否则返回arg2
    
        NULLIF(arg1,arg2) 
            如果arg1=arg2返回NULL;否则返回arg1        
    

    六、流程控制

    1、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 ;
    
    2、while循环语句
    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 ;
    
    3、repeat循环
    delimiter //
    CREATE PROCEDURE proc_repeat ()
    BEGIN
    
        DECLARE i INT ;
        SET i = 0 ;
        repeat
            select i;
            set i = i + 1;
            until i >= 5
        end repeat;
    
    END //
    delimiter ;
    
    4、loop
    BEGIN
        
        declare i int default 0;
        loop_label: loop
            
            set i=i+1;
            if i<8 then
                iterate loop_label;
            end if;
            if i>=10 then
                leave loop_label;
            end if;
            select i;
        end loop loop_label;
    
    END
    

    相关文章

      网友评论

          本文标题:47-视图,触发器,事务,存储过程,函数和流程控制

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