數據庫,多表數據

---恢復內容開始---python

多表數據:mysql

create table dep(
    id int primary key auto_increment,
    name varchar(16),
    work varchar(16)
);
create table emp(
    id int primary key auto_increment,
    name varchar(16),
    salary float,
    dep_id int
);
insert into dep values(1, '市場部', '銷售'), (2, '教學部', '授課'), (3, '管理部', '開車');
insert into emp(name, salary, dep_id) values('egon', 3.0, 2),('yanghuhu', 2.0, 2),('sanjiang', 10.0, 1),('owen', 88888.0, 2),('liujie', 8.0, 1),('yingjie', 1.2, 0);

emp
+----+----------+--------+--------+
| id | name     | salary | dep_id |
+----+----------+--------+--------+
|  1 | egon     |      3 |      2 |
|  2 | yanghuhu |      2 |      2 |
|  3 | sanjiang |     10 |      1 |
|  4 | owen     |  88888 |      2 |
|  5 | liujie   |      8 |      1 |
|  6 | yingjie  |    1.2 |      0 |
+----+----------+--------+--------+

dep
+----+-----------+--------+
| id | name      | work   |
+----+-----------+--------+
|  1 | 市場部    | 銷售   |
|  2 | 教學部    | 授課   |
|  3 | 管理部    | 開車   |
+----+-----------+--------+

多表鏈接=>虛擬的單表
內鏈接sql

左表 inner join 右表 on 兩表有關聯的字段的條件 
select  * from emp inner join dep on emp.dep_id = dep.id;

左鏈接 
左表 left join 右表 on 兩表有關聯的字段的條件
select * from  emp left join dep on emp.dep_id = dep.id;

右鏈接
左表 right join 右表  on 兩表有關聯的字段的條件

全鏈接
select * from emp left join dep  on emp.dep_id = dep.id
union
select * from emp right join dep on emp.dep_id = dep.id;

總結,內鏈接,兩表之間存在對應關係的行數纔會顯示
        左鏈接 左表全部行數都會顯示
        右鏈接 右表全部行數都會顯示
        全鏈接,將左鏈接和右鏈接的結果去重

練習:
查詢每一位員工對應的工做職責
select emp.name ,dep.work from emp left join dep on emp.dep_id = dep.id;
2.查詢每個部門下的員工們及員工職責
select  max(dep.name) "部門" , group_concat(emp.name)  "員工",max(dep.work)  "職責"  from emp right join dep on emp.dep_id = dep.id group by emp.dep_id;

pymysql模塊數據庫

#數據庫不存在報錯,用戶和密碼不正確報錯,port 爲數字,其餘都是字符串形式
1.創建鏈接
c = pymysql.connect(host = "localhost",port = 3306,db = "db5",user = "root",password = "123")

2.設置遊標
①cursor = c.cursor()#fetchone結果以元組輸出,fetchall的結果是元組,元素是每行元素組成的元組
②cursor = c.cursor(pymysql.cursors.DictCursor)#fetchone結果以字典輸出,fetchall的結果是列表,元素是每行元素組成的字典

3.書寫sql語句,並執行其結果
sql = "slect * from emp"
line = cursor.execute(sql)#返回數據總行數,修改或新增的話返回修改或新增的行數

查詢
都沒法讀出字段信息,沒有數據可讀時都不會報錯
①fetchone一次讀一行
②fetchmany(num)指定行數讀
③fetchall()全讀

4.指針移動:
cursor.scroll(num,mode)
#mode兩種(字符串)
①"relative"相對移動
#num>0 向前,num<0 向後
num可移動範圍報錯
②"absolute"絕對移動
num範圍0到line-1,超範圍報錯

5.提交,不提交的話,沒法保存修改和新增的數據
c.commit()

6.斷開鏈接
cursor.close()
c.close()

pymysql sql注入
mysql註釋:
/**/
-- 兩槓加空格fetch

根本原理:就根據程序的字符串拼接name='%s',咱們輸入一個xxx' -- haha,用咱們輸入的xxx加'在程序中拼接成一個判斷條件name='xxx' -- haha'指針

import pymysql
c = pymysql.connect(host ="localhost",port = 3306,db= "db5",user ="root",passwd="123")
cursor = c.cursor(pymysql.cursors.DictCursor)
name = input("input your name>>:").strip()
pwd = input("input your pwd>>:").strip()
sql = "select * from user where name = '%s' and pwd ='%s' "%(name,pwd)
line = cursor.execute(sql)
if line:
    print("login successful")
else:
    print("login fail")


input your name>>:bob
input your pwd>>:123
login successful


 "select * from user where name = '%s' and pwd ='%s' "
原理 name = '%s'    %s就是咱們輸入的數據
-- 後面會認爲是空格 須要 再加分號
select * from user where usr="aaa" or 1=1 -- hehe" and pwd="000";
知道用戶名時
bob';-- ' 兩個分號是匹配最外側兩個分號,也就是%s外面的兩個分號用
input your name>>:bob';-- '
input your pwd>>:fafadsfdsa
login successful
當不知道用戶名時
dsafa' or 1=1; -- '
input your name>>:dsafa' or 1=1; -- '
input your pwd>>:fdafsa
login successful

解決方案

# 原來是咱們對sql進行字符串拼接
# sql="select * from userinfo where name='%s' and password='%s'" %(user,pwd)
# res=cursor.execute(sql)

#改寫爲(execute幫咱們作字符串拼接,咱們無需且必定不能再爲%s加引號了)
sql="select * from userinfo where name=%s and password=%s" #!!!注意%s須要去掉引號,由於pymysql會自動爲咱們加上
res=cursor.execute(sql,[user,pwd]) #pymysql模塊自動幫咱們解決sql注入的問題,只要咱們按照pymysql的規矩來。

---恢復內容結束---code

相關文章
相關標籤/搜索