zoukankan      html  css  js  c++  java
  • 第四天(41道题全解) sql注入

    41道题:

    重要的
    连表查询
    分组
    
    制表语句:
        班级表
                   Table: class
            Create Table: CREATE TABLE `class` (
              `cid` int(11) NOT NULL AUTO_INCREMENT,
              `caption` varchar(50) DEFAULT NULL,
              PRIMARY KEY (`cid`)
            ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
            1 row in set (0.00 sec)
    
            
        学生表:
                           Table: student
            Create Table: CREATE TABLE `student` (
              `sid` int(11) NOT NULL AUTO_INCREMENT,
              `sname` varchar(50) DEFAULT NULL,
              `gender` char(10) DEFAULT NULL,
              `class_id` int(11) DEFAULT NULL,
              PRIMARY KEY (`sid`),
              KEY `fk_student_class` (`class_id`),
              CONSTRAINT `fk_student_class` FOREIGN KEY (`class_id`) REFERENCES `class` (`cid`)
            ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
                    
    
        老师表:
                           Table: teacher
            Create Table: CREATE TABLE `teacher` (
              `tid` int(11) NOT NULL AUTO_INCREMENT,
              `tname` varchar(50) DEFAULT NULL,
              PRIMARY KEY (`tid`)
            ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
            1 row in set (0.00 sec)
                            
                            
        课程表:
                          Table: course
            Create Table: CREATE TABLE `course` (
              `cid` int(11) NOT NULL AUTO_INCREMENT,
              `cname` char(25) DEFAULT NULL,
              `teacher_id` int(11) DEFAULT NULL,
              PRIMARY KEY (`cid`),
              KEY `fk_course_teacher` (`teacher_id`),
              CONSTRAINT `fk_course_teacher` FOREIGN KEY (`teacher_id`) REFERENCES `teacher` (`tid`)
            ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
            1 row in set (0.00 sec)
    
        成绩表:    
                
            create table score
                 (sid int not null auto_increment primary key,
                  student_id int not null,
                 corse_id int not null,
                 number int not null,
                 unique uq_sc (student_id,corse_id),
                 
                 CONSTRAINT fk_sc_st FOREIGN key (student_id) REFERENCES student(sid),
                 constraint fk_sc_co foreign key  (corse_id) references course(cid)
                 ) engine=innodb default charset=utf8;
                
                
        group by前面的slect 只能用聚合函数count,max什么的     
        
        
    v= 111 if 1==1 else 110 三元运算符
    #########################################################
    作业练习:
        http://www.cnblogs.com/wupeiqi/articles/5729934.html    
                
                
    http://www.cnblogs.com/wupeiqi/p/5748496.html  参考答案            
                
    ##########################################################
    
    用到的知识点
    - 临时表
            select * from (select * from tb where id< 10) as B;
            
        --- 
            select 
                id,
                name,
                1,
                (select count(1) from tb)----只要拿到的是一个值就可以
            from tb2
        ---把最外层的表s1,每次循环取一个常量值再到每一列中再循环一次    
            SELECT 
                student_id,
                (select num from score as s2 where s2.student_id=s1.student_id and course_id = 1) as 语文,
                (select num from score as s2 where s2.student_id=s1.student_id and course_id = 2) as 数学,
                (select num from score as s2 where s2.student_id=s1.student_id and course_id = 3) as 英语
            from score as s1;            
    
        ----avg(if(isnull(score.num),0,score.num))
             三目运算符
                
    #####################################################
    具体作业:
        1、自行创建测试数据
    
    2、查询“生物”课程比“物理”课程成绩高的所有学生的学号;
        PS:查出生物课程的学生,查出物理课程的学生,用临时表,再连接查询
            select A.student_id from 
            (select * from score 
            LEFT JOIN course on score.course_id=course.cid
            where course.cname="生物"
            ) as A
            LEFT JOIN  
            (select * from score 
            LEFT JOIN course on score.course_id=course.cid
            where course.cname="物理"
            ) as B 
            on A.student_id=B.student_id
            where A.num> B.num
    
    3、查询平均成绩大于60分的同学的学号和平均成绩; 
        select student_id, avg(num) from score GROUP BY student_id
        PS:把名字也带上
        select S.student_id,student.sname,S.av_s from 
        (SELECT student_id, avg(num) AS av_s FROM score GROUP BY student_id HAVING av_s > 60) as S
        LEFT JOIN student on student.sid=S.student_id
    
    4、查询所有同学的学号、姓名、选课数、总成绩;
        SELECT score.student_id,student.sname, COUNT(score.student_id),sum(score.num) from score 
        LEFT JOIN student ON score.student_id=student.sid
        GROUP BY score.student_id
    
    5、查询姓“李”的老师的个数;
        select COUNT(*) from teacher where teacher.tname 
        LIKE "李%"
    
    6、查询没学过“李平老师“课的同学的学号、姓名;
        PS:先查找李平的课程ID,再到score表中找学他的课的学生Id,再去student表中全部排除
        select student.sid,student.sname from student
        where student.sid not in 
        (
        select score.student_id from score
        where course_id in (select course.cid from course
        LEFT JOIN teacher on teacher.tid=course.cid
        where teacher.tname="李平老师")
        )
    
    7、查询学过“001”并且也学过编号“002”课程的同学的学号、姓名;
        PS:找出score表中学过课程1,或者2,或者1,2的学生,分组找出大于2的,再与学生表进行连接查询
        select student.sid,student.sname from score
        LEFT JOIN  student on score.student_id=student.sid
         where score.course_id=1 or score.course_id=2 GROUP BY score.student_id HAVING count(score.course_id)>1
    
    8、查询学过“叶平”老师所教的所有课的同学的学号、姓名;
        PS:语句分两部分B表是查出学过叶平老师所有课程的学生ID(注意其中叶平的课程有所变化所以不能count >2)
             再与学生表进行关联
        SELECT student.sid,student.sname FROM student
        LEFT JOIN 
            (
                SELECT score.student_id FROM score WHERE score.course_id 
                    IN (
                        SELECT cid FROM course
                        LEFT JOIN teacher ON teacher.tid = course.teacher_id
                        WHERE teacher.tname = "李平老师"
                       ) --查出叶平老师所教的课程的ID 
                GROUP BY score.student_id
                HAVING
                    count(score.student_id) = 
                    ( 
                        SELECT count(cid) FROM course LEFT JOIN teacher ON teacher.tid = course.teacher_id
                        WHERE teacher.tname = "李平老师" 
                    )        --查出叶平老师总共教了几门课count(cid)
            ) AS B             --查出学过叶平老师所有课程的学生ID
        ON student.sid = B.student_id
    
    
    9、查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名;
        PS:
            select student.sid,student.sname from student
            left JOIN 
                (select A.student_id from 
                        (select * from score 
                        LEFT JOIN course on score.course_id=course.cid
                        where course.cid=1
                        ) as A
                        LEFT JOIN  
                        (select * from score 
                        LEFT JOIN course on score.course_id=course.cid
                        where course.cid=2
                        ) as B 
                        on A.student_id=B.student_id
                        where A.num<B.num 
                ) as C 
            on student.sid=C.student_id
    
    10、查询有课程成绩小于60分的同学的学号、姓名;
            select sid,sname from student where sid in (
            select distinct student_id from score where num < 60
        )
    
    11、查询没有学全所有课的同学的学号、姓名;
        PS ---count要嘛用1要嘛用主键,效率高
        SELECT student.sid,student.sname from student
        INNER JOIN 
         (
            select score.student_id,count(1) from score GROUP BY score.student_id HAVING count(1) < (SELECT count(cid) from course)
         ) as B
        on student.sid = B.student_id
    
    12、查询至少有一门课与学号为“001”的同学所学相同的同学的学号和姓名;
        select student.sid,student.sname from student
        INNER JOIN
        (
        SELECT score.student_id,score.course_id from score where score.student_id !=1 
        and  score.course_id in (select score.course_id from score where score.student_id=1) GROUP BY score.student_id
        ) as B
        on student.sid=B.student_id
    
    13、查询至少学过学号为“001”同学所有课的其他同学学号和姓名
        select student.sid,student.sname from student
        INNER  JOIN
        (
            SELECT score.student_id,count(1) from score where score.student_id !=1 
                and  score.course_id in (select score.course_id from score where score.student_id=1) 
            GROUP BY score.student_id 
            HAVING count(1) = (select count(1) from score where score.student_id=1)
            ) AS B
        on student.sid=B.student_id
    
    14、查询和“002”号的同学学习的课程完全相同的其他同学学号和姓名;
        SELECT student_id from score where student_id 
        in (
            select student_id from score where student_id !=2 GROUP BY student_id 
                HAVING COUNT(1) =(select count(1) from score where student_id=1)
            ) 
        and course_id in (SELECT course_id from score where student_id =2) 
        GROUP BY student_id HAVING COUNT(1) = (SELECT count(1) from score where student_id)
    
    15、删除学习“叶平”老师课的SC表记录;
        delete from score where course_id in 
        (
          select cid from course left join teacher on course.teacher_id = teacher.tid where teacher.name = '叶平'
        )
    
    16、向SC表中插入一些记录,这些记录要求符合以下条件:①没有上过编号“002”课程的同学学号;②插入“002”号课程的平均成绩; 
        insert into score(student_id,course_id,num) 
        VALUES(select student_id,2,(select AVG(num) from score where course_id = 2) from score where course_id !=2) 
    
    17、按平均成绩从低到高显示所有学生的“语文”、“数学”、“英语”三门的课程成绩,按如下形式显示: 学生ID,语文,数学,英语,有效课程数,有效平均分;
           select s1.student_id,
           (select num from score left join course on score.course_id = course.cid where course.cname = "生物" and score.student_id=s1.student_id) as 生物,
            (select num from score left join course on score.course_id = course.cid where course.cname = "物理" and score.student_id=s1.student_id) as 物理,
            (select num from score left join course on score.course_id = course.cid where course.cname = "体育" and score.student_id=s1.student_id) as 体育,
            count(s1.course_id),
            avg(s1.num)
        from score as s1
        group by student_id desc
    
    18、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分;
        SELECT course_id,MAX(num),min(num) from score GROUP BY course_id
    
    19、按各科平均成绩从低到高和及格率的百分数从高到低顺序;
    
                select 
            course_id,avg(num),
            sum(case when num <60 THEN 0 ELSE 1 END),sum(1),
            sum(case when num <60 THEN 0 ELSE 1 END)/sum(1) as jgl 
            from score GROUP BY course_id order by AVG(num) asc,jgl desc;
    
    20、课程平均分从高到低显示(现实任课老师);
            select 
            course_id,avg(num),teacher.tname 
            from score
            LEFT JOIN course on score.course_id=course.cid
            left JOIN teacher on teacher.tid = course.teacher_id
            GROUP BY course_id desc
            
             select avg(if(isnull(score.num),0,score.num)),teacher.tname from course
        left join score on course.cid = score.course_id
        left join teacher on course.teacher_id = teacher.tid
     
        group by score.course_id
    
    21、查询各科成绩前三名的记录:(不考虑成绩并列情况) 
    
    22、查询每门课程被选修的学生数;
    SELECT student_id ,count(1) from score GROUP BY course_id HAVING COUNT(1) >5
    
    23、查询出只选修了一门课程的全部学生的学号和姓名;
    SELECT  student.sid,student.sname from student
    INNER  JOIN 
    (SELECT student_id ,count(1) from score GROUP BY student_id HAVING COUNT(1) =1) as B
    on student.sid=B.student_id
    
    24、查询男生、女生的人数;
    SELECT gender,COUNT(1) from student GROUP BY gender
    
    25、查询姓“张”的学生名单;
    SELECT sname from student where sname LIKE "张%"
    
    26、查询同名同姓学生名单,并统计同名人数;
    SELECT sname,count(1) from student GROUP BY sname
    
    27、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列;
    SELECT course_id,AVG(num) from score GROUP BY score.course_id ORDER BY avg(num) ASC,course_id DESC
    
    28、查询平均成绩大于85的所有学生的学号、姓名和平均成绩;
    SELECT sid,sname,T.B from student
    INNER  JOIN
    (SELECT student_id ,avg(if(ISNULL(num) ,0,num)) as B from score GROUP BY student_id HAVING B >85) as T
    on T.student_id=student.sid
    
    29、查询课程名称为“生物”,且分数低于60的学生姓名和分数;
        SELECT student.sname,score.num from course
        LEFT JOIN score on course.cid=score.course_id
        LEFT JOIN student on student.sid=score.student_id
         
        where course.cname='生物' and score.num < 60
    
    30、查询课程编号为003且课程成绩在80分以上的学生的学号和姓名;
    
        SELECT student.sname,score.num from course
        LEFT JOIN score on course.cid=score.course_id
        LEFT JOIN student on student.sid=score.student_id
        where course.cid=3 and score.num >80 
    
    31、求选了课程的学生人数
    SELECT count(DISTINCT(score.student_id)) from score
    
    32、查询选修“李平”老师所授课程的学生中,成绩最高的学生姓名及其成绩;
    
    SELECT student.sname,T.num from student
    INNER  JOIN 
    (SELECT * from teacher 
    LEFT JOIN course on teacher.tid=course.teacher_id
    LEFT JOIN score on score.course_id=course.cid
     GROUP BY num HAVING teacher.tname="张磊老师"  ORDER BY  num DESC LIMIT 0,1) as T
    on student.sid= T.student_id
    
    33、查询各个课程及相应的选修人数;
     select course.cname,count(1) from score
        left join course on score.course_id = course.cid
        group by course_id;
    
    34、查询不同课程但成绩相同的学生的学号、课程号、学生成绩;
    SELECT DISTINCT s1.student_id,s1.course_id,s1.num from score as s1,score as s2 WHERE s1.sid !=s2.sid and s1.course_id !=s2.course_id and s1.num=s2.num
    
    35、查询每门课程成绩最好的前两名;
     select score.sid,score.course_id,score.num,T.first_num,T.second_num from score left join
        (
        select
            sid,
            (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 0,1) as first_num,
            (select num from score as s2 where s2.course_id = s1.course_id order by num desc limit 1,1) as second_num
        from
            score as s1
        ) as T
        on score.sid =T.sid
        where score.num <= T.first_num and score.num >= T.second_num
    
    36、检索至少选修两门课程的学生学号;
    SELECT student_id from score GROUP BY student_id HAVING count(student_id) >1
    
    37、查询全部学生都选修的课程的课程号和课程名;
    
    38、查询没学过“叶平”老师讲授的任一门课程的学生姓名;
        PS:先查出学过李平老师任意一门课的学生,包括只选了一门的,然后,全部排除
        SELECT student.sid from student
        WHERE sid not in(
        SELECT score.student_id from score
        WHERE course_id in
        (
        SELECT  course.cid from course
         LEFT JOIN teacher on course.teacher_id=teacher.tid WHERE teacher.tname="李平老师"
         ))
    
    39、查询两门以上不及格课程的同学的学号及其平均成绩;
     select student_id,count(1) from score where num < 60 group by student_id having count(1) > 2
    
    40、检索“004”课程分数小于60,按分数降序排列的同学学号;
       select student_id from score where num< 60 and course_id = 4 order by num desc;
    
    41、删除“002”同学的“001”课程的成绩;
        delete from score where course_id = 1 and student_id = 2
    View Code

       sql注入代码样例:

    import pymysql
    
    user = input("username:")
    pwd = input("password:")
    
    conn = pymysql.connect(host="localhost",user='root',password='',database="db666")
    cursor = conn.cursor()
    sql = "select * from userinfo where username='%s' and password='%s'" %(user,pwd,)
    # select * from userinfo where username='uu' or 1=1 -- ' and password='%s'  
    #根本的原因是因为有--注释掉后passwor,而1=1是永真,所以一定不能自己来拼接用户名密码
    cursor.execute(sql)
    result = cursor.fetchone()
    cursor.close()
    conn.close()
    
    if result:
        print('登录成功')
    else:
        print('登录失败')
    View Code

    为防止sql注入应当使用pymysql自带的excute的参数传递,支持字典,列表,字符串

    import pymysql
    
    user = input("username:")
    pwd = input("password:")
    
    conn = pymysql.connect(host="localhost",user='root',password='',database="db666")
    cursor = conn.cursor()
    sql = "select * from userinfo where username=%s and password=%s"
    #sql = "select * from userinfo where username=%(u)s and password=%(p)s"
    cursor.execute(sql,user,pwd)  #防止sql注入的方法
    # cursor.execute(sql,[user,pwd])
    # cursor.execute(sql,{'u':user,'p':pwd})
    result = cursor.fetchone()
    cursor.close()
    conn.close()
    if result:
        print('登录成功')
    else:
        print('登录失败')
    View Code

    sql多行插入

     1 import pymysql
     2 
     3 # 增加,删,该
     4 #conn = pymysql.connect(host="localhost",user='root',password='',database="db1")
     5 #cursor = conn.cursor()
     6 #sql = "insert into userinfo(username,password) values('root','123123')"
     7 ## 受影响的行数
     8 #r = cursor.execute(sql)
     9 # #  ******
    10 #conn.commit()
    11 #cursor.close()
    12 #conn.close()
    13 
    14 conn = pymysql.connect(host="localhost",user='root',password='',database="db1")
    15 cursor = conn.cursor()
    16 # # sql = "insert into userinfo(username,password) values(%s,%s)"
    17 # # cursor.execute(sql,(user,pwd,))
    18 #
    19 sql = "insert into userinfo(username,password) values(%s,%s)"
    20 # r 是 受影响的行数
    21 r = cursor.executemany(sql,[('egon','sb'),('laoyao','BS')])
    22 # #  ******
    23 conn.commit()
    24 cursor.close()
    25 conn.close()
    26 "s3.p
    View Code

    pymysql模块:
    pip3 install pymysql -i https://pypi.douban.com/simple
    Python模块:对数据库进行操作(SQL语句)

    1. Python实现用户登录
    2. MySQL保存数据


    - 连接、关闭(游标)
    - execute() -- SQL注入
    - 增删改: conn.commit()
    - fetchone fetchall
    - 获取插入数据自增ID

  • 相关阅读:
    利用知名站点欺骗挂马
    海量数据库解决方案
    利用第三方浏览器漏洞钓鱼
    WCF的用户名+密码认证方式
    启用 Master Data Services 的 Web Service
    ExtJS 4.1有什么值得期待?
    [笔记]软件框架设计的艺术
    Master Data Server API 更新 Member 内置字段(Code、Name)
    Master Data Service调用API创建Model
    Silverlight传值
  • 原文地址:https://www.cnblogs.com/wanchenxi/p/8076148.html
Copyright © 2011-2022 走看看