上课笔记

重点:(熟练)
多表查询
创建存储过程
原生sql
索引原理
pymysql  封装好的客户端
cursor 底层就是一个send操作
commit 告诉mysql真的要完成修改操作(不然修改不会生效)
execute 执行
查询不需要commit password(‘123’) 可以得到hash,mysql自带的 sql中--代表注释 后面都无效 sql注入 不需要账号,密码就可登陆网站了
跳过前端筛选,所以在应用程序也要在检测
怎么解决sql注入问题
popen 看一下 cursor.fetchall() 拿到查询的结果 从管道里拿值 ctrl /注释 ctrl shift /解除注释 视图不要改,只是为了方便查询,不需要重复连接 以后视图轻易不要用,查询有变动要联系别人DBA修改,很麻烦,不推荐用,自己的数据库可以用视图 delimiter 重新声明一下sql语句结束标志
结束后需要还原 delimiter; transaction 事务,交易
但凡遇到转账,交易之类需要用 rollback 回滚 遇到commit回滚就是修改后的数据 存储过程 封装视图,触发器,函数等 直接调用存储过程名
无参存储过程
delimiter $$
create procedure p1()
BEGIN
......
END
delimiter ; delimiter $$
create procedure p1()
BEGIN
declare n int default 1;
while (n<100) do
insert into s1 values(n,concat('egon',n),'male',concat('egon',n,'@163.com'));
set n = n+1;
end while;
......
END
delimiter ; 基于pymysql模块的增删改查

1.基于pymysql插入操作(有注释)
 import pymysql

 # 首先要建立和数据库的链接
client=pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='egon123',
database='db6',
charset='utf8'
) cursor1=client.cursor() # cursor是游标,执行结果默认返回元组 sql='insert into t1 values(1,"egon");' # 插入sql语句
try:
res=cursor1.execute(sql) # 执行sql语句
print(res)
client.commit() # 加上commit告诉mysql需要完成插入修改操作,不加插入不会生效。
except Exception: # 如果sql语句执行出现异常捕捉到就执行回滚操作,把执行成功的语句都撤销
client.rollback() cursor1.close() # 最后记得关闭游标
client.close() # 关闭连接

基于pymysql执行插入操作

2.-- 是mysql语句中注释

1、sql注入之一:用户存在,绕过密码
egon' -- 任意字符 2、sql注入之二:用户不存在,绕过用户与密码
xxx' or 1=1 -- 任意字符 1=1是True
sql注入 不需要账号,密码就可登陆网站了
现在网站不让输入特殊字符,就是因为这个原因。
跳过前端筛选,所以在应用程序也要在检测。
3.基于pymysql增删操作(有注释)
 import pymysql

 client=pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='egon123',
database='db6',
charset='utf8'
) cursor=client.cursor() sql='insert into t1 values(3,"alex"),(4,"lxx");'
userinfo=[
(3,"alex"),
(4,"lxx"),
(5,"yxx")
]
for user in userinfo: # 插入操作
sql='insert into t1 values(%s,"%s");' %(user[0],user[1])
# print(sql)
cursor.execute(sql) # 返回的是执行成功的行数 sql='insert into t1 values(%s,%s);'
cursor.executemany(sql,userinfo) # 插入多条记录,它的运行原理就是循环userinfo。 cursor.execute('delete from t1 where id=3;') # 删除操作 client.commit() # 这个想要修改成功必须要加 cursor.close()
client.close()

基于pymysql增删操作

4.基于pymysql在数据库中进行查询

4.1 存在注入问题的登陆

 import pymysql

 client=pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='egon123',
database='db6',
charset='utf8'
) cursor=client.cursor()
#查询
inp_user=input('输入账号名: ').strip()
inp_pwd=input('输入密码: ').strip()
# 在sql语句里password(字符串) 执行hash操作,一般我们不用,都会调用hashlib来完成
# sql='select id from user where name = "%s" and pwd = password("%s");' %(inp_user,inp_pwd)
sql='select id from user where name = "%s" and pwd = "%s";' %(inp_user,inp_pwd)
print(sql)
rows=cursor.execute(sql) # 返回的是行数,执行成功rows就不为0,if rows就为True
if rows: # rows返回值不为0,就显示登陆成功
print('\033[45m登陆成功\033[0m')
else:
print('\033[46m用户名或密码错误\033[0m') cursor.close() # 日常两个关闭操作
client.close()

存在注入问题

4.2 解决注入问题(有注释)

 import pymysql

 client=pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='egon123',
database='db6',
charset='utf8'
) cursor=client.cursor()
#查询
inp_user=input('输入账号名: ').strip()
inp_pwd=input('输入密码: ').strip() # 放到cursor.execute()里,sql语句会把%s自动识别为字符串,不需要再加引号
sql='select id from user where name = %s and pwd = %s;'
rows=cursor.execute(sql,(inp_user,inp_pwd))
if rows:
print('\033[45m登陆成功\033[0m')
else:
print('\033[46m用户名或密码错误\033[0m') cursor.close()
client.close()

解决注入问题

4.3 获取查询结果

 # 提交查询语句并且拿到查询结果
import pymysql client=pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='egon123',
database='db6',
charset='utf8'
) cursor=client.cursor(pymysql.cursors.DictCursor)
#查询 sql='select * from user where id > 3'
rows=cursor.execute(sql)
print(rows)
print(cursor.fetchall()) # 获得所有的记录
print(cursor.fetchall()) print(cursor.fetchone()) # 获得一个记录
print(cursor.fetchone())
print(cursor.fetchone()) print(cursor.fetchmany(2)) # 获得多个记录,括号里可以指定记录
print(cursor.fetchone()) print(cursor.fetchall())
# cursor.scroll(0,mode='absolute') # 绝对位置移动
# cursor.scroll(1,mode='absolute') # 绝对位置移动
print(cursor.fetchall()) print(cursor.fetchone())
cursor.scroll(2,mode='relative') # 相对当前位置移动
print(cursor.fetchone()) cursor.close()
client.close()

获取查询结果

05-08 15:26