• Navicat-pymysql-sql注入问题


    一、Navicat 可视化工具的使用

    1、Navicat [1]  是一套快速、可靠并价格相宜的数据库管理工具,专为简化数据库的管理及降低系统管理成本而设。

    它的设计符合数据库管理员、开发人员及中小企业的需要。Navicat 是以直觉化的图形用户界面而建的,

    让你可以以安全并且简单的方式创建、组织、访问并共用信息。

    #要求掌握
        1;测试+连接数据库
        2:新建库
        3:新建表,新增字段+类型+约束条件的创建
        4:设计表:外键
        5:新建查询
        6:建立表的模型
        7:转储/运行SQL文件
        8:通过模型多表之间查询,输入命令

    #注意
      批量加注释:ctrl+?建
      批量去注释:CTRL+shift+?建

    2、 软件操作界面及使用注意事项:

    3、新建库时注意事项:

    4、可以把建好的表转储为SQL文件保存下来,可以把新的SQL文件直接添加并运行(可以直接利用别人建好的框架模型或数据)

    二、练习题:(多表之间的查询)

    1、查询所有的课程的名称以及对应的任课老师姓名
    4、查询平均成绩大于八十分的同学的姓名和平均成绩
    7、 查询没有报李平老师课的学生姓名
    8、 查询没有同时选修物理课程和体育课程的学生姓名
    9、 查询挂科超过两门(包括两门)的学生姓名和班级
    
    # 解题步骤:
        把复杂的问题拆分,按条件拆分一步一的写,再基于上一次查询的结果再做条件筛选

    1:查询所有的课程的名称以及对应的任课老师姓名

    解题思路:(1):先采用连表操作 inner join(内连接把老师和课程的信息查找)   

    select *from course inner join teacher on course.teacher_id =teacher.tid; 内连接查找

          (2):在找到老师和课程的基础上,再查找课程对应的老师信息

            把 * 换成要查找的内容即可:

    SELECT
        course.cname,
        teacher.tname
    FROM
        course
    INNER JOIN teacher ON course.teacher_id = teacher.tid;

    2:查询平均成绩大于八十分的同学的姓名和平均成绩

    '''SELECT
        student.sname,
        t1.avg_num
    FROM
        student       # 第二步:查询学生符合符合条件的学生 再用avg
    INNER JOIN (
        SELECT
            student_id,
            avg(num) AS avg_num
        FROM
            score      # 第一步:先查找平均成绩大于80分的同学
        GROUP BY  
            student_id
        HAVING        # 分组后的条件筛选
            avg(num) > 80
    ) AS t1 ON student.sid = t1.student_id;'''

    3: 查询没有报李平老师课的学生姓名(找出报名李平老师课程的学生,然后取反就可以)

    SELECT
        student.sname
    FROM
        student
    WHERE
        sid NOT IN (
            SELECT DISTINCT
                student_id
            FROM
                score
            WHERE
                course_id IN (
                    SELECT
                        course.cid
                    FROM
                        course
                    INNER JOIN teacher ON course.teacher_id = teacher.tid
                    WHERE
                        teacher.tname = '李平老师'
                )
        );

    4、 查询没有同时选修物理课程和体育课程的学生姓名(没有同时选修指的是选修了一门的,

      思路是得到物理+体育课程的学生信息表,然后基于学生分组,统计count(课程)=1)

    SELECT
        student.sname
    FROM
        student
    WHERE
        sid IN (
            SELECT
                student_id
            FROM
                score
            WHERE
                course_id IN (
                    SELECT
                        cid
                    FROM
                        course
                    WHERE
                        cname = '物理'
                    OR cname = '体育'
                )
            GROUP BY
                student_id
            HAVING
                COUNT(course_id) = 1
        );

    5、查询挂科超过两门(包括两门)的学生姓名和班级

    select student.sname,class.caption from class INNER JOIN student
        on class.cid = student.class_id
        WHERE student.sid in 
        (select student_id from score where num < 60
        GROUP BY student_id
        HAVING COUNT(course_id) >=2)

    三、pymysql 模块

    命令行安装: pip insatll mysql   用Python来实现操作mysql

    import pymysql
    
    conn = pymysql.connect(
        host = '127.0.0.1',
        port = 3306,
        user = 'root',
        password = '123',
        database = 'day38',
        charset = 'utf8'  # 编码千万不要加- 如果写成了utf-8会直接报错
    )
    # 向mysqld服务端发送请求连接
    
    cursor = conn.cursor(pymysql.cursors.DictCursor)  # 产生一个游标对象 以字典的形式返回查询出来的数据 
    # 键是表的字段 值是表的字段对应的信息
    sql = 'select * from teacher'
    
    cursor.execute(sql)    # 执行传入的sql语句
    print(cursor.fetchone())  # 只获取一条数据
    print(cursor.fetchone())  # 只获取一条数据
    
    # cursor.scroll(2,'absolute')  # 控制光标移动   absolute相对于其实位置 往后移动几位
    cursor.scroll(1,'relative')    # relative相对于当前位置 往后移动几位
    print(cursor.fetchall())    # 获取所有的数据  返回的结果是一个列表

    四、mysql 注入问题

     解决在输入没有密码或者用户名错误的情况下也能访问数据的问题。

    # 2.代码链接
    import pymysql
    #链接
    conn=pymysql.connect(
      host='localhost',
      user='root',
      password='123',
      database='egon',
      charset='utf8')
    #游标
    cursor=conn.cursor() #执行完毕返回的结果集默认以元组显示
    #cursor=conn.cursor(cursor=pymysql.cursors.DictCursor)  # 以字典的方式显示数据
    
    # 3.pymysql操作数据库
    #执行sql语句
    user = input(">>>:").strip()
    pwd = input(">>>:").strip()
    sql='select * from userinfo where name="%s" and password="%s"' %(user,pwd) #注意%s需要加引号
    
    rows=cursor.execute(sql) #执行sql语句,返回sql查询成功的记录数目
    # 获取真实数据cursor.fetchone(),cursor.fetchall(),cursor.fetchmany(),类似管道取值,获取一条,所有,多条
    
    cursor.scroll(1,'relative')  # 相对移动
    cursor.scroll(3,'absolute')  # 绝对移动
    
    
    cursor.close()
    conn.close()


    sql注入的问题:

      通过修改验证方式,解决在没有输入正确的用户名和密码时也能获取数据的情况

    import  pymysql
    
    conn = pymysql.connect(
        host = '127.0.0.1',
        port = 3306,
        user = 'root',
        password = '123',
        database = 'day38',
        charset = 'utf8'  # 编码千万不要加- 如果写成了utf-8会直接报错
    )
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    
    username =input('username>>>:').strip()
    password = input('password>>>:').strip()
    
    sql ="select * from userinfo where name = %s and password = %s"
    print(sql)
    res = cursor.execute(sql,(username,password)) # execute 会自动识别sql语句中的%s 帮你做替换
    if res:
        print(cursor.fetchall())
    else:
        print("用户名和密码错误!")

    结果:
    username>>>:james
    password>>>:123
    select * from userinfo where name = %s and password = %s
    [{'id': 2, 'name': 'james', 'password': '123'}]
    """ sql注入 就是利用注释等具有特殊意义的符号 来完成一些骚操作
    后续写sql语句 不要手动拼接关键性的数据 而是让excute帮你去做拼接
    """
    sql ="select * from userinfo where name = %s and password = %s" %(username,password)
    res = cursor.execute(sql)

    如果这么写的话会出现注入问题:利用mysql -- 注释的语法实现破解密码 如输入:Jack‘-- bhgdj 或 xxx' or 1=1 没有密码不知道用户名也能获取数据

    五、增删改

    conn.commit()   手动提交

    autocommit = True  自动提交

    import  pymysql
    
    conn = pymysql.connect(
        host = '127.0.0.1',
        port = 3306,
        user = 'root',
        password = '123',
        database = 'day38',
        charset = 'utf8',  # 编码千万不要加- 如果写成了utf-8会直接报错
    autocommit = True  # 这个参数配置完成后  增删改操作都不需要在手动加conn.commit了
    )
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    
    sql = 'insert into userinfo (name,password) values("jerry","666")'
    # sql = 'update userinfo set name = "jasonhs" where id = 1'
    # sql = 'delete from userinfo  where id = 2'
    cursor.execute(sql)
    
    # conn.commit()

    """ 增删改操作 都必须加一句 conn.commit()操作 """

      

     

      

          

      

  • 相关阅读:
    类的加载机制与反射 笔记
    json
    人人都是产品经理 笔记
    java IO
    jcrop+jquery+javaweb 实现头像裁剪、上传
    C++学习-3
    C++学习-2
    C++学习-1
    Django高级部分
    Django---模板
  • 原文地址:https://www.cnblogs.com/Gaimo/p/11394492.html
Copyright © 2020-2023  润新知