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()操作 """

 

 

 

  

 

 

 

 

  

 

 

      

  

posted @ 2019-08-23 14:44  游走De提莫  阅读(338)  评论(0编辑  收藏  举报