zoukankan      html  css  js  c++  java
  • MySQL自带功能介绍

    前言:

    数据库相关的操作

    1.SQL语句 *****(MySql(一)已经介绍

    2.利用mysql内部提供的功能(视图、触发器、函数、存储过程

    一、视图:

    把经常使用的查询结果,做成临时视图表,保存方便反复使用;

    1、创建视图:

    CREATE VIEW zhanggen as  SELECT * FROM score;

    2、查看视图:

    SELECT * FROM zh;

    3、删除视图

    drop view zh

    二、触发器

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

    1.插入前触发器:

    格式:创建触发器  名称  BEFORE INSERT(操作 前/后)  on 表   FOR EACH ROW(没插入一条数据触发器执行一次)


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

    2、插入后 触发器

    格式:创建触发器  名称  AFTER INSERT(操作 前/后)  on 表   FOR EACH ROW(没插入一条数据触发器执行一次)


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

    3、删除前触发器

    格式:创建触发器  名称   BEFORE DELETE(操作 前/后)  on 表   FOR EACH ROW(没插入一条数据触发器执行一次)
    CREATE TRIGGER tri_before_delete_tb1 BEFORE DELETE ON tb1 FOR EACH ROW
    BEGIN
    ...触发器
    END

    4、删除后触发器

    格式:创建触发器  名称   AFTER DELETE (操作 前/后)  on 表   FOR EACH ROW(没插入一条数据触发器执行一次)
    CREATE TRIGGER tri_after_delete_tb1 AFTER DELETE ON tb1 FOR EACH ROW
    BEGIN
    ...
    END

    5、更新前触发器

    格式:创建触发器  名称   BEFORE UPDATE  (操作 前/后)  on 表   FOR EACH ROW(没插入一条数据触发器执行一次)
    CREATE TRIGGER tri_before_update_tb1 BEFORE UPDATE ON tb1 FOR EACH ROW
    BEGIN
    ...
    END

    6、更新后触发器

    格式:创建触发器  名称   AFTER UPDATE(操作 前/后)  on 表   FOR EACH ROW(没插入一条数据触发器执行一次)

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

    7、

    NEW,代指新数据 (更新)
    OLD,代指老数据 (删除)

    delimiter //:修改SQL语句的结束符

    insert into tb (....)

    delimiter //
    create trigger t1 BEFORE INSERT on student for EACH ROW
    BEGIN
    INSERT into teacher(tname) values(NEW.sname);
    INSERT into teacher(tname) values(NEW.sname);
    INSERT into teacher(tname) values(NEW.sname);
    INSERT into teacher(tname) values(NEW.sname);
    END //
    delimiter ;

    insert into student(gender,class_id,sname) values('女',1,'陈涛'),('女',1,'张根');

    三、函数

    1、SQL语句的内置函数(max(),min(),count()...)

    CHAR_LENGTH(str)
            返回值为字符串str 的长度,长度的单位为字符。一个多字节字符算作一个单字符。
            对于一个包含五个二字节字符集, LENGTH()返回值为 10, 而CHAR_LENGTH()的返回值为5。
    
        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)
            变大写
    
        LTRIM(str)
            返回字符串 str ,其引导空格字符被删除。
        RTRIM(str)
            返回字符串 str ,结尾空格字符被删去。
        SUBSTRING(str,pos,len)
            获取字符串子序列
    
        LOCATE(substr,str,pos)
            获取子序列索引位置
    
        REPEAT(str,count)
            返回一个由重复的字符串str 组成的字符串,字符串str的数目等于count 。
            若 count <= 0,则返回一个空字符串。
            若str 或 count 为 NULL,则返回 NULL 。
        REPLACE(str,from_str,to_str)
            返回字符串str 以及所有被字符串to_str替代的字符串from_str 。
        REVERSE(str)
            返回字符串 str ,顺序和字符顺序相反。
        RIGHT(str,len)
            从字符串str 开始,返回从后边开始len个字符组成的子序列
    
        SPACE(N)
            返回一个由N空格组成的字符串。
    
        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'
    
        TRIM([{BOTH | LEADING | TRAILING} [remstr] FROM] str) TRIM(remstr FROM] str)
            返回字符串 str , 其中所有remstr 前缀和/或后缀都已被删除。若分类符BOTH、LEADIN或TRAILING中没有一个是给定的,则假设为BOTH 。 remstr 为可选项,在未指定情况下,可删除空格。
    
            mysql> SELECT TRIM('  bar   ');
                    -> 'bar'
    
            mysql> SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx');
                    -> 'barxxx'
    
            mysql> SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx');
                    -> 'bar'
    
            mysql> SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz');
                    -> 'barx'
    
    部分内置函数
    View Code

     

    需要记住:

    SELECT CURDATE()查询当前时间;

     

    data_format(ctime,"%Y-%m"):设置时间类型数据的格式;(在内存修改,不会改掉原数据;(通过月group by 就可设计博客园,每月博客统计的效果;)

     

     

    2、自定义函数:

    注意 1、函数必须有返回值 2、函数体不能出现select * from 表 

     自定义函数(有返回值):


    delimiter \

    create function f1(
    i1 int,
    i2 int)
    returns int
    BEGIN
    declare num int default 0;
    set num = i1 + i2;
    return(num);
    END \
    delimiter ;

    SELECT f1(1,100);

    调用:SELECT f1(1,100);

    3、调用函数

    执行函数 select 函数名();

     

    四、普通存储过程


    1.什么是存储过程:

    在数据库里保存别名 -------《封装一堆SQL语句操作》,开发人员直接调用别名,无需要程序里写SQL语句了;


    2.功能:

    替代程序员写SQL语句;


    3.公司中常见的 数据库使用场景:

    方式1:
    在数据库里面:保存存储过程别名;
    在程序里面: 直接调用 存储过程别名;

    方式2:
    在程序里面语句写 SQL

    方式3:

    在程序里写 类和对象;(通过程序中写好的库,转换成SQL语句)

    4、存储过程的定义:


    4.1. 简单无参数存储过程

    create procedure p1()
    BEGIN
    select * from student;
    INSERT into teacher(tname) values("ct");
    END

    call p1()
    cursor.callproc('p1')

    4.2、带参数的存储过程

    delimiter //
    create procedure p3(
    in n1 int,
    inout n2 int
    )
    BEGIN
    set n2 = 123123;
    select * from student where sid > n1;
    END //
    delimiter ;

    5、存储过程的调用:

    5.1.在mysql端调用存储过程别名:

    set @v1 = 10;(设置变量(session))在session级别创建变量:set @变量名

    call p2(12,@v1) 调用存储过程,返回存储过程执行的结果集;

    select @v1; 查看了out参数返回的值

    5.2Python调用存储过程别名:

    查看存储过程的结果集:

    cursor.callproc('p3',(12,2))
    r1 = cursor.fetchall()
    print(r1)

    查看out参数返回的值:注意

    cursor.execute('select @_p3_0,@_p3_1')
    r2 = cursor.fetchall()
    print(r2) 

    6、参数 in、out、inout参数的意义

    in:普通值,给存储过程内部传值,在存存储过程外部无法获取;

    out:变量,给存储过程外部输出值,在存储过程内部无法使用;

    inout变量:既能在存储过程内部使,还可以有返回值;


    7、大波课上一问:为什么有存储过程执行完了返回了结果集,还需要 out参数的返回值?

    delimiter //
    create procedure p3(
    in n1 int,
    out n2 int
    out n3 int)

    BEGIN
    insert into vv(..) set n2= 1
    insert into vv(..)
    insert into vv(..)
    insert into vv(..)
    insert into vv(..)
    insert into vv(..) set n3=6

    END //
    delimiter;

    利用out返回值,判断存储过程的执行状态,n2=1 执行到了insert1 n3=6执行到了insert=6;

    8、阿根课上一疑?存储过程封装了SQL语句,和TND上面说函数不是一样一样滴吗?

    答:不是的

    1、函数不可以封装 查询类型的SQL语句

    3、参数不一样 存储过程的函数 分in/out/inout三类,函数没有

    2、调用方式不一样(函数select,存储过程call)

    五、支持事务的存储过程

    delimiter //
                create procedure p4(
                    out status int
                )
                BEGIN
                    1. 声明如果出现异常则执行{
                        set status = 1;
                        rollback;
                    }
                       
                    开始事务
                        -- 由秦兵账户减去100
                        -- 方少伟账户加90
                        -- 张根账户加10
                        commit;
                    结束
                    
                    set status = 2;
                    
                    
                END //
                delimiter ;
                
                ===============================
                delimiter \
                create PROCEDURE p5(
                    OUT p_return_code tinyint
                )
                BEGIN 
                  DECLARE exit handler for sqlexception 
                  BEGIN 
                    -- ERROR 
                    set p_return_code = 1; 
                    rollback; 
                  END; 
                 
                  START TRANSACTION; 
                    DELETE from tb1;
                    insert into tb2(name)values('seven');
                  COMMIT; 
                 
                  -- SUCCESS 
                  set p_return_code = 2; 
                 
                  END\
                delimiter ;
    View Code

    六. 游标+存储过程(相当于Python的for循环,对表中列,一一设置。)

    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(number) values(temp);
                        end loop xxoo;
                    close my_cursor;
                    
                    
                end  //
                delimter
    View Code

    七. 存储过程+动态执行SQL(防SQL注入)

    delimiter //
                create procedure p7(
                    in tpl varchar(255),
                    in arg int
                )
                begin 
                    1. 预检测某个东西 SQL语句合法性
                    2. SQL =格式化 tpl + arg 
                    3. 执行SQL语句
                    
                    set @xo = arg;
                    PREPARE xxx FROM 'select * from student where sid > ?';
                    EXECUTE xxx USING @xo;
                    DEALLOCATE prepare prod; 
                end  //
                delimter ;
            
            
                
                call p7("select * from tb where id > ?",9)
            
                ===> 
        
                delimiter \
                CREATE PROCEDURE p8 (
                    in nid int
                )
                BEGIN
                    set @nid = nid;
                    PREPARE prod FROM 'select * from student where sid > ?';
                    EXECUTE prod USING @nid;
                    DEALLOCATE prepare prod; 
                END\
                delimiter ;
    View Code

    八、Python的操作MySQL (pymysql模块)

    1、用户、密码在mysql,python实现用户登录

    import pymysql
    user=input("username:").strip()
    pwd=input("password:").strip()
    conn=pymysql.connect(host="192.168.182.128",user="eric",password="123123",database="day58") #数据库连接对象
    cursor=conn.cursor(cursor=pymysql.cursors.DictCursor)   #创建游标对象(打开数据库的小手)
                                                            # cursor=pymysql.cursors.DictCursor参数会把fetch到的结果变成,字典套元组的格式;
    sql="select * from user_info where name= %s and passwd= %s"
    cursor.execute(sql,[user,pwd])                          # pymysql的excute([参数1,参数2])方法,会自动帮我们做字符串拼接,并检查SQL注入
    res=cursor.fetchone()
    print(res)
    print("登录成功") if  res else print("用户/密码错误")
    cursor.close()
    conn.close()
    View Code

    2、插入300W条数据

    import  pymysql
    conn=pymysql.connect(host="192.168.182.128",user="eric",password="123123",database="day61")
    cursor=conn.cursor(cursor=pymysql.cursors.DictCursor)
    for i in range(3000000):
        i=str(i)
        name=i+'alex'
        gender="man"
        email=name+"@163.com"
        sql = "insert into user(name,gender,email)values(%s,%s,%s)"
        cursor.execute(sql,[name,gender,email])
        if cursor.lastrowid%500000==0:
            print(cursor.lastrowid)   # cursor.lastrowid 属性获取最后一条数据的自增ID
            conn.commit()    # 注意不要忘记:conn.commit()提交了事物,数据库中的数据才会更新;
    else:print("插入完成!")
    cursor.close()      # 最后记得:关闭游标、关闭连接
    conn.close()
    View Code

    九、数据库操作总结

    1、SQL语句(MySQL一博客)重要常用

    2、利用mysql内部提供的功能(视图、触发器、函数、存储过程)

  • 相关阅读:
    Windows下的符号链接
    简单谈谈存储器的容量缩水问题
    配置CKEditor和CKFinder
    CKFinder的水印控件的问题
    关于 Visual Studio 默认创建的不是公共类
    Symbian 60 按键以及对应的键值(图)
    PLC中存储器的数据类型与寻址方式
    S7200 寻址
    电工识图笔记
    S7200型号串口通信参数设置
  • 原文地址:https://www.cnblogs.com/sss4/p/6973316.html
Copyright © 2011-2022 走看看