zoukankan      html  css  js  c++  java
  • 数据库04 /多表查询、pymysql模块

    数据库04 /多表查询、pymysql模块

    1. 笛卡尔积

    将两表所有的数据一一对应,生成一张大表(可能有重复的字段名)
    select * from dep,emp;  -- 两张表拼在一起
    select * from  ,emp where dep.id=emp.dep_id;  -- 找到两表之间对应的关系记录
    select * from dep,mep where dep.id=emp.dep_id and dep.name='技术';  -- 筛选部门名称为技术的大表中的记录
    select emp.name from dep,emp where dep.id = emp.dep_id and dep.name='技术';  -- 拿到筛选后的记录的员工姓名字段数据
    
    展示出来是虚拟的表,和平时单表的约束条件不一样,可能有重名,原表可能设置为非空,连表后可能为空
    

    2. 连表查询

    2.1 inner join 内连接

    第一步:连表
    	select * from dep inner join emp on dep.id=emp.dep_id;
    2.过滤
    	select * from dep inner join emp on dep.id=emp.dep_id where dep.name = '技术';
    3.找对应数据
    	select emp.name from dep inner join emp on dep.id=emp.dep_id where dep.name = '技术';
    

    2.2 left join 左连接

    left join  左连接
    -- left join左边的表为主表,主表记录必须全部显示,辅表没办法对应上的,就通过null来补全
    -- 左边显示dep,右边显示emp
    
    select * from dep left join emp on dep.id=emp.dep_id;
    

    2.3 right join 右连接

    right join  右连接
    -- right join右边的表为主表,主表记录必须全部显示,辅表没办法对应上的,就通过null来补全
    -- 左边显示dep,右边显示emp
    
    select * from dep right join emp on dep.id=emp.dep_id;
    

    2.4 union全连接

    mysql> select * from dep left join emp on dep.id=emp.dep_id
        -> union
        -> select * from dep right join emp on dep.id=emp.dep_id;
        
    union与union all的区别:
     - union会去掉相同的纪录,因为union all是left join 和right join合并,所以有重复的记录,
     - 通过union就将重复的记录去重了。
    

    3. 子查询

    1.一个查询结果集作为另一个查询的条件
    select name from emp where dep_id = (select id from dep where name = '技术');
    2、带比较运算符的子查询
        比较运算符:=、!=、>、>=、<、<=、<>
        如:查询大于所有人平均年龄的员工名与年龄
    3、带EXISTS关键字的子查询
      EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录。而是返回一个真假值。True或False
      当返回True时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询。还可以写not exists,和exists的效果就是反的
    
    3.总结:
     - 1:子查询是将一个查询语句嵌套在另一个查询语句中。
     - 2:内层查询语句的查询结果,可以为外层查询语句提供查询条件。
     - 3:子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字
     - 4:还可以包含比较运算符:= 、 !=、> 、<等
    

    4. pymysql模块

    4.1 python代码读取mysql数据库

    import pymysql
    conn = pymysql.connect(
        host='127.0.0.1',
        port=3306,
        user='root',
        password='666',
        database='day43',
        charset='utf8',
    )
    
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    # 默认游标取出的数据是 ((),)
    # DictCursor 对应的数据结构 [{},],如果用的是fetcheone,那么结果是{}.
    sql = "select * from dep;"
    
    ret = cursor.execute(sql)   # ret 受影响的行数
    
    print(ret)
    print(cursor.fetchmany())   # 不写参数,默认是一条
    print(cursor.fetchone())
    print(cursor.fetchall())
    
    print('----------')
    cursor.scroll(2,'absolute')   # absolute 绝对移动,相对于数据最开始的位置进行光标的移动
    cursor.scroll(2,'relative')   # relative 相对移动,按照光标当前位置来进行光标的移动
    
    print(cursor.fetchone())
    

    4.2 python代码增删改mysql数据库

    import pymysql
    conn = pymysql.connect(
        host='127.0.0.1',
        port=3306,
        user='root',
        password='666',
        database='day43',
        charset='utf8',
    )
    
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    
    sql = "insert into t1 values (3,'xx3',18);"
    
    ret = cursor.execute(sql)
    
    print(ret)
    
    # 增删改都必须进行提交操作(commit)
    conn.commit()   # 提交
    

    4.3 sql注入

    SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

    sql的注释符:--

    import pymysql
    conn = pymysql.connect(
        host='127.0.0.1',
        port=3306,
        user='root',
        password='666',
        database='day43',
        charset='utf8',
    )
    
    while 1:
        username = input('请输入用户名:')
        password = input('请输入密码:')
    
        cursor = conn.cursor(pymysql.cursors.DictCursor)
        sql = "select * from userinfo where username='%s' and password='%s';" % (username, password)
        
        # sql注入
        # sql = "select * from userinfo where username='zhangsan '-- ' and password='%s';"% (username, password) 
        # 知道用户名不知道密码,登录网站(输入张三" -- "即可登录)
        
        # sql = "select * from userinfo where username='aaa' or 1=1 -- ' and password='%s';" % (username, password) 
        # 不知道用户名也不知道密码,登录网站(输入aaa"or 1=1 -- "即可登录)
        
        # pymysql解决sql注入问题
        sql = "select * from userinfo where username=%s and password=%s;"
        ret = cursor.execute(sql,[username,password])
        if ret:
            print('登录成功')
        else:
            print('账号或者密码错误,请重新输入!!!')
    
    # 增删改都必须进行提交操作(commit)
    conn.commit()
    

    4.4 pymysql总结

    import pymysql
    conn = pymysql.connect(
        host='127.0.0.1',   # 主机ip
        port=3306,   # 端口号
        user='root',   # 用户名
        password='666',   # 密码
        database='day43'   # 需要连接的库
        charset='utf8'
    )
    cursor = conn.cursor()
    sql = "select * from dep;"
    ret = cursor.excute(sql)   # ret受影响的行数
    print(cursor.fetchall())   # 取出所有的
    print(cursor.fetchmany(3))   # 取出多条
    print(cursor.fetchone())   # 取出单条
    
    cursor.scroll(3,'absolute')   # 绝对移动,按照数据最开始位置往下移动3条
    cursor.scroll(3,'relative')   # 相对移动,按照当前光标位置往下移动3条
    
    conn.commit()   # 增删改操作时,需要进行提交
    
    
    sql注入:解决方案
    	cursor.execute(sql,[参数1,参数2...])
    两种场景:
        知道用户名不知道密码 or 1=1
        不知道用户名也不知道密码 ' -- (--后面有一个空格)
        不能通过字符串格式化来写
        cursor.execute(sql,[参数1,参数2...])相当于是去掉特殊符号去掉
    
  • 相关阅读:
    GDUFE ACM-1020
    GDUFE ACM-1069(简单的巴什博弈)
    GDUFE ACM-1138
    GDUFE ACM-1009
    GDUFE ACM-1008
    GDUFE ACM-1005
    LCA 最近公共祖先
    51nod
    51nod
    51nod
  • 原文地址:https://www.cnblogs.com/liubing8/p/11482988.html
Copyright © 2011-2022 走看看