zoukankan      html  css  js  c++  java
  • day 43 python链接mysql(注入)、事务、【视图、函数、存储过程、触发器】

    pymysql (Python操作MySQL)

    import pymysql
    conn = pymysql.connect(
    host='localhost',
    user='root',
    password='999',
    database='db1',
    charset='utf8'
    )
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    sql = "insert into t8 (name,email) values (%s,%s)"
    data = []
    for i in range(3000000):
    num = random.randint(0, 3000000)
    data.append(('root%s' % num, 'root%s@qq.com' % num))

    cursor.executemany(sql, data) #执行多条
    cursor.execute(sql,(data)) # 执行一条
    conn.commit()
    cursor.close()
    conn.close()

    注意:
    a. conn, cursor 用完了需要关闭资源连接
    b. 查询的时候, fetchone, fetchmany, fetchall, 默认返回的是元组, 需要返回字典的话: cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    c. 删除和更新的时候, 需要在execute之后, 添加 conn.commit()

    今日内容:

    PyMySQL: (*******************************)

    a. 登录验证

    写sql语句的时候, %传值的时候, 需要加引号:
    sql = "select * from t4 where name = '%s' and pwd = '%s'" % (username, pwd)

    上面的sql语句带来的风险是:

    例一:
    username = 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()
    cursor.lastrowid : 最后一行的行数

    事务: (**************************************************************************************************)

    一组操作, 要么都成功, 要么都失败

    特性:
      原子性: 一组操作, 要么都成功, 要么都失败
      一致性(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; 显示全部类型
    --------------------------------------------------------------------------

    下面这些了解:
    一、视图:
      产生的原因:
        如果有一个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;

      问题: 如果原生的表数据发生了变化, 那视图会不会发生变化? 也会变化
        一般不会单独修改视图中的数据,但是还是可以改

        update test set name='jerry';

        update v1 set name='owen';

      应用场景:
        MySQL: (DBA)
        生成视图View
      程序:调用 select * from v1;

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


    三、存储过程: 将一大堆 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;  #查看是否执行了sql语句

    四、触发器:在满足对某张表增、删、改的情况下,自动触发的功能称之为触发器【向用户表中添加一条数据的同时, 在日志表中也添加一条记录】

      delimiter //
      CREATE TRIGGER t1 BEFORE INSERT ON t7 FOR EACH ROW
      BEGIN
      insert into t11 (name, money) values ('xxx', 1234);
      END //
      delimiter ;

    为可要用触发器?
    触发器专门针对我们对某一张表数据增insert、删delete、改update的行为,
    这类行为一旦执行就会触发触发器的执行,即自动运行另外一段sql代码

    创建触发器语法
    #针对插入
    create trigger tri_after_insert_t1 after insert on 表名 for each row
    begin
    sql 代码...
    end

    create trigger tri_before_insert_t2 before insert on 表名 for each row
    begin
    sql 代码...
    end

    #针对删除
    create trigger tri_after_delete_t1 after delete on 表名 for each row
    begin
    sql 代码...
    end

    create trigger tri_before_delete_t2 before delete on 表名 for each row
    begin
    sql 代码...
    end

    #针对修改
    create trigger tri_after_update_t1 after update on 表名 for each row
    begin
    sql 代码...
    end

    create trigger tri_before_update_t2 before update on 表名 for each row
    begin
    sql 代码...
    end
  • 相关阅读:
    遍历文件下所有文件
    访问网址(使用CDN)时 智能DNS调度 与 用户定位调度(根据IP定位)
    UV,IP,PV
    vector list deque
    mailto: HTML e-mail 链接
    freemarker 用template快速构造XML
    Oracle varchar2 length 分析
    Flex grid 复杂表头
    Oracle 动态设置SEQUENCE startwith 的值
    ssh和ssh2之间的免密码登陆详解
  • 原文地址:https://www.cnblogs.com/qingqinxu/p/11040133.html
Copyright © 2011-2022 走看看