zoukankan      html  css  js  c++  java
  • Python全栈之路-MySQL(四)

    1 上下连表

    union # 自动去重
    union # 不去重
    select sid,sname from student 
    union
    select sid,teacher from teacher
    
    select sid,sname from student 
    union all
    select sid,teacher from student
    

    2 基于角色的权限管理

    用户信息表
    id username pwd role_id
    
    权限表
    id privilege_name
    
    角色表
    id role_name
    
    角色权限管理
    id privilege_id role_id
    
    1.基于角色的权限管理
    2.需求分析
    
    
    http://www.cnblogs.com/wupeiqi/articles/5713323.html
    

    3 视图(虚拟表)

    相当于给临时表起了个别名,方便日后使用

    - 创建视图
    create view v1 as select * from student where sid > 10;
    - 使用视图
    select * from v1;
    - 修改视图
    alter view v1 as select * from student where sid < 10;
    - 删除视图
    drop view v1; 
    

    4 触发器(不常使用)

    当对某张表做增删改操作时,可以使用触发器在操作前后自定义关联行为

    1 插入前

    CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
    BEGIN
        ...
    END
    

    2 插入后

    CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW
    BEGIN
        ...
    END
    

    3 删除前

    CREATE TRIGGER tri_before_delete_tb1 BEFORE DELETE ON tb1 FOR EACH ROW
    BEGIN
        ...
    END
    

    4 删除后

    CREATE TRIGGER tri_after_delete_tb1 AFTER DELETE ON tb1 FOR EACH ROW
    BEGIN
        ...
    END
    

    5 更新前

    CREATE TRIGGER tri_before_update_tb1 BEFORE UPDATE ON tb1 FOR EACH ROW
    BEGIN
        ...
    END
    

    6 更新后

    CREATE TRIGGER tri_after_update_tb1 AFTER UPDATE ON tb1 FOR EACH ROW
    BEGIN
        ...
    END
    

    实例:

    delimiter //
    create trigger t1 before insert on student for each row
    begin
        insert into teacher(tname) values('teacher01');
    end
    delimiter ;
    
    
    delimiter //
    CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
    BEGIN
    
    IF NEW.NAME == 'alex' THEN
        INSERT INTO tb2 (NAME)
    VALUES
        ('aa')
    END
    END//
    delimiter ;
    
    delimiter //
    CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW
    BEGIN
        IF NEW.num = 666 THEN
            INSERT INTO tb2 (NAME)
            VALUES
                ('666'),
                ('666') ;
        ELSEIF NEW.num = 555 THEN
            INSERT INTO tb2 (NAME)
            VALUES
                ('555'),
                ('555') ;
        END IF;
    END//
    delimiter ;
    
    NEW 代指新数据 insert操作
    OLD 代指老数据 delete update 
    

    5 函数

    • 内置函数:max min avg sum count curdate
    • 自定义函数

    内置函数实例:

    blog 文章按月分组,显示月份和文章数
    id  title ctime
    1   t1    2019-11-10 11:10
    2   t2    2019-11-10 13:10
    3   t3    2019-12-10 14:10
    4   t4    2019-12-10 16:10
    
    select ctime,count(1) from blog group by ctime
    select DATA_FORMAT(ctime,"%Y-%m),count(1) from blog group by DATA_FORMAT(ctime,"%Y-%m) 
    
    
    delimiter \
    create function f1(
        i1 int,
        i2 int)
    returns int
    BEGIN
        declare num int;
        set num = i1 + i2;
        return(num);
    END \
    delimiter ;
    
    select f1(1,100);
    

    6 存储过程

    保存在mysql服务端上的一个别名 => 一坨SQL语句

    简单的存储过程

    delimiter //
    create procedure p1()
    BEGIN
        select * from student;
        insert into teacher(tname) values ('teacher02');
    END //
    delimiter ;
    call p1();
    
    # pymysql执行存储过程
    cursor.callproc('p1')
    result = cursor.fetchall()
    print(result)
    

    传参数的存储过程(in out inout 三种参数类型)

    参数in 传给函数内部使用 
    delimiter //
    create procedure p2(
        in n1 int,
        in n2 int
    )
    BEGIN
        select * from student where sid > n1;
        insert into teacher(tname) values ('teacher02');
    END //
    delimiter ;
    call p2(5,10);
    
    # pymysql执行存储过程
    cursor.callproc('p2',(5,10))
    result = cursor.fetchall()
    print(result)
    
    参数out 返回给外面使用
    delimiter //
    create procedure p3(
        in n1 int,
        out n2 int
    )
    BEGIN
        set n2 = 123123;
        select * from student where sid > n1;
        insert into teacher(tname) values ('teacher02');
    END //
    delimiter ;
    set @v1 = 0; -- session级别全局变量
    call p3(5,@v1); -- 返回值赋给@v1
    select @v1;
    
    # pymysql执行存储过程
    cursor.callproc('p3',(5,10))
    result = cursor.fetchall()
    print(result)
    cursor.execute('select @_p3_0,@_p3_1')
    result = cursor.fetchall()
    print(result)
    
    参数inout:既能传进去使用,也能返回来使用
    
    支持事务的存储过程
    delimiter \
    create PROCEDURE p5(
        OUT p_return_code tinyint
    )
    BEGIN 
      DECLARE exit handler for sqlexception 
      BEGIN 
        -- ERROR 
        set p_return_code = 1; 
        rollback; 
      END; 
     
      DECLARE exit handler for sqlwarning 
      BEGIN 
        -- WARNING 
        set p_return_code = 2; 
        rollback; 
      END; 
     
      START TRANSACTION; 
        DELETE from tb1;
        insert into tb2(name)values('seven');
      COMMIT; 
     
      -- SUCCESS 
      set p_return_code = 0; 
     
      END\
    delimiter ;
    
    

    存储过程里的游标
    注意:游标的效率不高,当要对单独的表的每一行数据进行分门别类的操作时才使用游标

    delimiter //
    create procedure p6()
    begin 
        declare row_id int; -- 自定义变量1  
        declare row_num int; -- 自定义变量2  
        DECLARE done INT DEFAULT FALSE;
        declare temp int;
    
    
        DECLARE my_cursor CURSOR FOR select id,num from a;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
        
        open my_cursor;
            xxoo: LOOP
                fetch my_cursor into row_id,row_num;
                if done then 
                    leave xxoo;
                END IF;
                set temp = row_id + row_num;
                insert into b(num) values(temp);
            end LOOP xxoo;
        close my_cursor;
    end  //
    delimiter ;
    CALL p6()
    

    动态执行SQL(防SQL注入)

    delimiter \
    CREATE PROCEDURE p7 (
        in nid int
    )
    BEGIN
        set @nid = nid;
        PREPARE prod FROM 'select * from student where sid > ?';
        EXECUTE prod USING @nid;
        DEALLOCATE prepare prod; 
    END\
    delimiter ;
    call p7(10);
    

    总结:

    1.可传参 in out inout
        out或inout 可用来标识存储过程执行成功与否
    2.pymysql操作
    3.数据库相关操作
        - SQL语句 *****
        - 利用MySQL内部提供的功能
    
  • 相关阅读:
    vi/vim系统编辑命令使用技巧
    C++基础之智能指针
    C++基础之volatile关键字
    C++基础之强制类型转换
    C++基础之左值、右值与移动语义
    C++基础之对象模型
    C++基础之运行时类型识别RTTI
    C++基础之指针与引用的底层实现
    深度学习之参数计算(CNN为例)
    数学基础之勾股数
  • 原文地址:https://www.cnblogs.com/wanyuetian/p/7000536.html
Copyright © 2011-2022 走看看