1. 程式人生 > >5月11日 python學習總結 子查詢、pymysql模塊增刪改查、防止sql註入問題

5月11日 python學習總結 子查詢、pymysql模塊增刪改查、防止sql註入問題

hal port 註入 any dict lex absolut username 參數

一、子查詢   

子查詢:把一個查詢語句用括號括起來,當做另外一條查詢語句的條件去用,稱為子查詢

select emp.name from emp inner join dep on emp.dep_id = dep.id where dep.name="技術";

select name from emp where dep_id =
(select id from dep where name="技術");


查詢平均年齡在25歲以上的部門名
select name from dep where id in
(select dep_id from emp group by dep_id having avg(age) > 25);

select dep.name from emp inner join dep on emp.dep_id = dep.id
group by dep.name
having avg(age) > 25;

查看不足2人的部門名(子查詢得到的是有人的部門id)

   

  補:exists存在

select * from emp where exists (
select id from dep where id > 3
);


查詢每個部門最新入職的那位員工

select t1.id,t1.name,t1.post,t1.hire_date,t2.post,t2.max_date from emp as t1 inner join
(select post,max(hire_date) as max_date from emp group by post) as t2
on t1.post = t2.post
where t1.hire_date = t2.max_date
;

二、pymysql模塊

基本操作之查詢:  

import pymysql #pip3 install pymysql

conn=pymysql.connect(
    host=127.0.0.1,
    port=3306,
    user=root,
    password=123,
    database=db42,
    charset=utf8
)
cursor=conn.cursor(pymysql.cursors.DictCursor)  #查詢結果以字典形式顯示

sql=select * from class;
rows=cursor.execute(sql)   #
執行一條sql語句,返回值是執行結果的行數 print(rows) print(cursor.fetchone()) #取出一行執行結果,光標向後移動一位 print(cursor.fetchone()) #取出第二行執行結果 光標向後移動一位 print(cursor.fetchmany(2)) #取出兩行執行結果 光標向後移動兩位 print(cursor.fetchall()) #取出剩余的全部 print(cursor.fetchall()) # print(cursor.fetchall()) # cursor.scroll(3,‘absolute‘) # 絕對路徑 光標從最開始的位置開始向後移動3個位置 # print(cursor.fetchone()) #取出當前光標所在位置的數據,並將光標後移 print(cursor.fetchone()) print(cursor.fetchone()) cursor.scroll(1,relative) #相對路徑 光標從當前位置開始向後移動3個位置 print(cursor.fetchone()) conn.commint() #提交事務 cursor.close() conn.close()

  基本操作之增改:

import pymysql #pip3 install pymysql

conn=pymysql.connect(
    host=127.0.0.1,
    port=3306,
    user=root,
    password=123,
    database=db42,
    charset=utf8
)
cursor=conn.cursor(pymysql.cursors.DictCursor)

#一次插入一行記錄
sql=insert into user(username,password) values(%s,%s)  
rows=cursor.execute(sql,(EGON,123456))
print(rows)
print(cursor.lastrowid)

rows=cursor.execute(update user set username="alexSB" where id=2)
print(rows)

# 一次插入多行記錄
sql=insert into user(username,password) values(%s,%s)
rows=cursor.executemany(sql,[(lwz,123),(evia,455),(lsd,333)])
print(rows)
print(cursor.lastrowid)

conn.commit() # 只有commit提交才會完成真正的修改
cursor.close()
conn.close()

三、防止sql註入問題 

1、當輸入 正確的用戶名 並在其後加上 ‘--‘ sql註釋符時, 我們執行這條sql 後邊的密碼驗證判斷就被註釋掉了,從而沒有密碼就可以登錄

2、 或者 在用戶輸入用戶名時,隨意輸入用戶名 並加上 ‘or 1=1‘ 這種語句,則跳過了賬戶密碼的驗證直接登陸進去了

所以rows=cursor.execute(sql)這種拼接sql ,直接執行的方法並不可靠   

import pymysql #pip3 install pymysql

conn=pymysql.connect(
    host=127.0.0.1,
    port=3306,
    user=root,
    password=123,
    database=db42,
    charset=utf8
)
cursor=conn.cursor(pymysql.cursors.DictCursor)


inp_user=input(用戶名>>:).strip() #inp_user=""
inp_pwd=input(密碼>>:).strip() #inp_pwd=""
sql="select * from user where username=‘%s‘ and password=‘%s‘" %(inp_user,inp_pwd)

#1、當輸入 正確的用戶名 並在其後加上 ‘--‘  sql註釋符時, 我們執行這條sql  後邊的密碼驗證判斷就被註釋掉了,從而沒有密碼就可以登錄
#2、 或者  在用戶輸入用戶名時,隨意輸入用戶名 並加上 ‘or 1=1‘ 這種語句,則跳過了賬戶密碼的驗證直接登陸進去了

rows=cursor.execute(sql)  #所以這種拼接sql ,直接執行的方法並不可靠
if rows:
    print(登錄成功)
else:
    print(登錄失敗)

cursor.close()
conn.close()

  解決辦法:

pymysql 為我們提供了過濾字符串中特殊符號的功能

  使用如下方法傳入參數,會自動幫我們過濾掉特殊字符,防止sql註入  

inp_user=input(用戶名>>:).strip() #inp_user=""
inp_pwd=input(密碼>>:).strip() #inp_pwd=""
sql="select * from user where username=%s and password=%s"

rows=cursor.execute(sql,(inp_user,inp_pwd))

5月11日 python學習總結 子查詢、pymysql模塊增刪改查、防止sql註入問題