Python day43 :pymysql模块/查询,插入,删除操作/SQL注入完全问题/事务/模拟登录注册服务器/视图/函数/存储过程

## pymysql模块

```python
pymysql模块 
#通过pymysql跟mysqld 服务器建立连接
流程:
import pymysql
conn=pymysql.connect(host="localhost",user="root",password="123",dababase="db1",charset="utf8")
localhost:本地主机,与"127.0.0.1"有一点不同:传输数据不需要经过网卡
cursor=conn.cursor(cursor=pymysql.cursors.DictCursor)
#cursor:游标,在游标下执行sql语句.
#cursor=pymysql.cursors.DictCursor,表示后面fetch取出数据的格式是字典类型(列表里面套字典)
sql="select*from student where id>%s"%(12,)
cursor.excute(sql)
res=cursor.fetchone()#取出一条数据
res=cursor.fetchmany(10)#取出10条数据
res=cursor.fetchall()#取出所有类型

cursor.close()#关闭游标对象
conn.close()#关闭连接对象


```

## 插入删除操作

```python
import pymysql
conn=pymysql.connect(host="localhost",user="root",password="123",database="db1",charset="utf8")
cursor= conn.cursor(cursor=pymysql.cursors.DictCursor)
sql="delete from t1 where id=3"
cursor.execute(sql)
#删除和更新的时候,需要事物提交
connn.commit()
cursor.close()
conn.close()

```

## 模拟登录注册服务器编程

```python
a. 登录验证
写sql语句的时候, %传值的时候, 需要加引号:
sql = "select * from t4 where name = '%s' and pwd = '%s'" % (username, pwd)
上面的sql语句带来的风险是:
例一:
    sername = zekai' #
    select * from t4 where name = 'zekai' #' and pwd = ''
例二:
    username = dbsahvbdsha' or 1=1 #
    select * from t4 where name = 'dbsahvbdsha' or 1=1 
    '上面出现的问题,我们称之为 SQL注入!!!' 
出现问题的根源是:
            因为太过于相信用户的输入, 导致我们在接受用户输入的参数的时候, 并没有对他进行转义
解决SQL注入:
        1. 自己手工对用户输入的值进行转义
        2. 使用execute()自动进行过滤
sql = "select * from t4 where name = %s and pwd = %s" 
cursor.execute(sql,(username, pwd))
# 插入一条:
        cursor.execute(sql, ('lxxx', '1234'))
# 插入多条:
        data = [
                ('aaaaa', 'aaa'),
                ('bbbb', 'bbb'),
                ('ffff', '666'),
                ('rrrr', '888'),
            ]
        cursor.executemany(sql, data)
        try:
            cursor.execute(sql, ('lxxx', '1234'))
            #  删除和更新的时候, 需要事物提交
            conn.commit()
        except Exception as e:
            conn.rollback()#回滚
            'rollback():回滚,返回到执行失败之前
```

```python
import  pymysql
# 连接mysql服务器
username = input('username:')
pwd = input('password:')

conn = pymysql.connect(host='localhost', user='root', password='123',database='db1', charset='utf8')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)

sql = "select * from t4 where name = %s and pwd = %s"
# 对用户输入的值进行转义
cursor.execute(sql,(username, pwd))
res = cursor.fetchone()
print(res)
if res:
    print('登录成功')
else:
    print('登录失败')
cursor.close()
conn.close()

```

## 事务:

```python
一组操作, 要么都成功, 要么都失败
特性:
    原子性: 一组操作, 要么都成功, 要么都失败
    一致性(Consistency):指事务发生前和发生后,数据的总额依然匹配
    隔离性(Isolation):简单点说,某个事务的操作对其他事务不可见的
    持久性(Durability):当事务完成后,其影响应该保留下来,不能撤消,只能通过“另开起一个事物”来抵消之前的错误
        
场景:
    思考:
                我去银行给朋友汇款,
                我卡上有1000元,
                朋友卡上500元,
                我给朋友转账100元(无手续费),
                如果,网线断了, 我的钱刚扣,而朋友的钱又没加时, 怎么办?
    create table t11 (id int auto_increment primary key,
    name varchar(32) not null default '',money int not null default 0)engine=Innodb  charset=utf8;
    insert into t11 (name,money) values ('zekai', 1000), ('eagon', 500);
解决方法:
        开启事务 (start transaction)
        (执行sql操作)
        commit : 提交上面的SQL, 让其生效
        rollback: 回滚
        show full tables;  显示全部类型

```

## 视图

```python
视图:
产生的原因:
    如果有一个SQL语句频繁的会被使用到,比如说:
    select * from t4 where id>12 and id <24;
    搞一个映射,或者取一个别名
    select * from t4 where id>12 and id <24   === > v1
    视图:
        select * from v1;
    创建视图:
        create view v1 as select * from t4 where id>12 and id <24;
    修改视图:
         alter view v1 as sql语句;    
    删除视图:
        drop view v1;
    问题:
        如果原生的表数据发生了变化, 那视图会不会发生变化?
        也会变化
    视图中的数据会不会发生修改? 不会发生修改    
        应用场景:
            MySQL: (DBA)
                生成视图View
            程序:
                调用  select  * from v1;

```

## 函数

```python
函数:
    不要轻易使用
    在程序中, 用代码计算, 计算好了, 再传给SQL语句执行
```

## 存储过程

```python
将一大堆 SQL 语句进行封装, 类似于函数, 结果就是存储过程
MySQL服务端:DBA (写)
a. 简单的存储过程:
    delimiter //
    create procedure p1()
    BEGIN
    select * from t11;
    END //
    delimiter ;
    程序:
    call p1();
b. 传参数: (in)
    delimiter //
    create procedure p2(in n1 int,in n2 int)
    BEGIN
    select * from t11 where id > n1;
    END //
    delimiter ;
    程序:
    call p2(12, 2)
c. 传入参数: (out)
    delimiter //
    create procedure p3(in n1 int,out n2 int)
    BEGIN
    select * from t11 where id > n1;
    set n2 =  1;
    END //
    delimiter ;
    set @v2=123212;
    call p3(12, @v2);
    select @v2;

```

## 触发器

```python
触发器:
    向用户表中添加一条数据的同时, 在日志表中也添加一条记录
    delimiter //
    CREATE TRIGGER t1 BEFORE INSERT ON t7 FOR EACH ROW
    BEGIN
    insert into t11 (name, money) values ('xxx', 1234);
    END //
    delimiter ;
```

 

posted @ 2019-06-17 21:47  Python-Man  阅读(233)  评论(0编辑  收藏  举报