5月11日 python學習總結 子查詢、pymysql模塊增刪改查、防止sql註入問題
一、子查詢
子查詢:把一個查詢語句用括號括起來,當做另外一條查詢語句的條件去用,稱為子查詢
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註入問題