---恢复内容开始---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