zoukankan      html  css  js  c++  java
  • day 35 MySQL基础、pymysql模块

    MySQL基础

    文档:MySQL 简单语句.note

    链接:http://note.youdao.com/noteshare?id=12a1b3f29691065ad702e5f854cb5a2b&sub=F6867B5A6B6F485CB447AF8254BFC4A5

    文档:数据类型.note

    链接:http://note.youdao.com/noteshare?id=6fc535e5da39abc8eba647ee229db106&sub=355C83259E53493B8FE2B9CDDEBF06D1

    文档:约束条件.note

    链接:http://note.youdao.com/noteshare?id=abf9d67f7ece25ef02114d6537bc6f17&sub=6076879C36024939B18A6633DF0AED1A

    文档:表关系.note

    链接:http://note.youdao.com/noteshare?id=fab9bd9e77a3a5a9503a93dc48a3b849&sub=386FCC60E8854E1F9DDFDCB8206A5551

    文档:单表查询-简单查询.note

    链接:http://note.youdao.com/noteshare?id=eae244f1bd93552d611420d9af7784bb&sub=47DC12E0E62B4F96BBFC46DF877D749C

    文档:单表查询-关键字.note

    链接:http://note.youdao.com/noteshare?id=d77814944d26084d1eb45f0a07c41653&sub=9D23E660917B4CD896200E9528A11E92

    文档:多表查询-链接.note

    链接:http://note.youdao.com/noteshare?id=446685fa345e2bf6eb89b3093ef31229&sub=40BAFCE73DA24260AC5840265E196564

    文档:权限管理.note

    链接:http://note.youdao.com/noteshare?id=55822dae1a6d179ca88a48e87dc477c1&sub=B7FC2200FE274C91BAC0D5DB1254E23C

    文档:MySQL 内置功能.note

    链接:http://note.youdao.com/noteshare?id=7e0d006831062553d5215b9ae4596164&sub=491F9C7F65F14CC59439D987B2E5BD9D

    文档:索引.note

    链接:http://note.youdao.com/noteshare?id=acd2d5d92e9460135cc848bec3363e1f&sub=F1C0504642DD42CA9CBE1A1E327D7882

    pymysql模块

    介绍

    之前我们都是通过MySQL自带的命令行客户端工具mysql来操作数据库,那如何在python程序中操作数据库呢?这就用到了pymysql模块,该模块本质就是一个套接字客户端软件,使用前需要事先安装。

    pip3 install pymysql

    链接、执行sql、关闭(游标)

    # 基本使用
    import pymysql
    
    user = input('>>>').strip()
    pawd = input('>>>').strip()
    
    # 建立连接
    info = pymysql.connect(
        host='192.168.42.23',
        port=3306,
        user='root',
        password='123123',
        db='TestDB',
        charset='utf8'
    )
    
    # 获取游标
    cur = info.cursor()
    
    # 执行SQL
    sql = 'select * from info where user = "%s"and pawd = "%s"' % (user, pawd)
    rows = cur.execute(sql)     # 获取执行成功后的行数
    print(rows)
    
    # 关闭游标,释放资源
    cur.close()
    info.close()
    
    if rows:
        print('登录成功')
    else:
        print('登录失败')

    execute()之sql注入

    注意:符号--会注释掉它之后的sql,正确的语法:--后至少有一个任意字符

    根本原理:就根据程序的字符串拼接name='%s',我们输入一个xxx' -- haha,用我们输入的xxx加'在程序中拼接成一个判断条件name='xxx' -- haha'

    最后那一个空格,在一条sql语句中如果遇到select * from t1 where id > 3 -- and name='egon';则--之后的条件被注释掉了
    
    #1、sql注入之:用户存在,绕过密码
    egon' -- 任意字符
    
    #2、sql注入之:用户不存在,绕过用户与密码
    xxx' or 1=1 -- 任意字符

     

     解决方法:

    # 原来是我们对sql进行字符串拼接
    # sql="select * from userinfo where name='%s' and password='%s'" %(user,pwd)
    # print(sql)
    # 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的规矩来。
    # 修改如下:在执行SQL部分,代码拼接使用 execute() 进行拼接
    
    # 执行SQL
    sql = 'select * from info where user = %s and pawd = %s'
    rows = cur.execute(sql,(user,pawd))     # 获取执行成功后的行数
    print(rows)

    增、删、改:conn.commit()

    增删改的用法一致。

    # sql 执行部分
    # 增 删 改
    sql = 'insert into info(user,pawd) values(%s,%s) '
    row = cursor.execute(sql,('qwe','123123'))      # 插入一条
    print(row)    # 1,受影响的行数
    
    row = cursor.executemany(sql, [('test', '123123'), ('test2', '123123'), ('test3', '123123')])
    print(row)      # 3

    获取插入的最后一条数据的自增ID

    # sql 执行部分
    # 增 删 改
    sql = 'insert into info(user,pawd) values(%s,%s)'
    row = cursor.executemany(sql, [('test4', '123123'), ('test5', '123123'), ('test6', '123123')])
    print(cursor.lastrowid)     # 获取插入数据之前关标的位置,库中现在有6条数据,那么关标的位置就是 7 。

    查:fetchone,fetchmany,fetchall

    默认返回元组列表。在取数据时,每取到一次数据,关标也会跟随移动。

    # sql 执行部分
    #
    rows = cursor.execute('select * from info')   # 执行sql语句,返回sql影响成功的行数rows,将结果放入一个集合,等待被查询
    # print(cursor.fetchone())        # (1, 'ysg', '123')
    # print(cursor.fetchone())        # (2, 'czx', '123')
    print(cursor.fetchone())          # (3, 'pei', '123')
    
    print(cursor.fetchall())          # ((1, 'ysg', '123'), (2, 'czx', '123'), (3, 'pei', '123'), (9, 'qwe', '123123')...)
    print(cursor.fetchmany(3))        # ((1, 'ysg', '123'), (2, 'czx', '123'), (3, 'pei', '123'))

    pymysql.cursors.DictCursor  A cursor which returns results as a dictionary,将结果作为字典返回的游标

    # 获取游标
    # A cursor which returns results as a dictionary 将结果作为字典返回的游标
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    
    #
    rows = cursor.execute('select * from info')
    print(cursor.fetchone())        # {'id': 1, 'user': 'ysg', 'pawd': '123'}
    print(cursor.fetchall())        # [{'id': 2, 'user': 'czx', 'pawd': '123'}, {'id': 3, 'user': 'pei', 'pawd': '123'}...]
    print(cursor.fetchmany(3))        # [{'id': 1, 'user': 'ysg', 'pawd': '123'}, {'id': 2, 'user': 'czx', 'pawd': '123'}, {'id': 3, 'user': 'pei', 'pawd': '123'}]

    关标的移动

    cursor.scroll(2, mode='relative') ,默认为 mode='relative',相对位置。

    # sql 执行部分
    #
    rows = cursor.execute('select * from info')
    
    print(cursor.fetchone())
    cursor.scroll(2, mode='relative')  # 默认为 mode='relative',相对位置
    print(cursor.fetchone()) 
    
    # 执行结果
    {'id': 1, 'user': 'ysg', 'pawd': '123'}
    {'id': 4, 'user': 'qwe', 'pawd': '123123'}

    cursor.scroll(6, mode='absolute')  # 绝对位置

    # sql 执行部分
    #
    rows = cursor.execute('select * from info')
    
    print(cursor.fetchone())
    cursor.scroll(2, mode='absolute')  # 绝对位置
    print(cursor.fetchone())
    
    # 执行结果
    {'id': 1, 'user': 'ysg', 'pawd': '123'}
    {'id': 3, 'user': 'pei', 'pawd': '123'}

     存储过程

    无参数

    mysql 存储过程

    -- 格式
    delimiter //
    create PROCEDURE p1()
    BEGIN
        select * from info;
    END //
    delimiter;
    
    -- 执行
    call p1();

    有参数

    mysql 存储过程

    delimiter //
    create procedure p2(in t1 int,in t2 int,out res_t int)  -- in 表示传入值,out 表示返回值
    begin 
        select * from info f where f.id>=t1 and f.id<=t2;
        set res_t = 1;    -- 设置执行成功后修改的返回值
    end //
    delimiter;
    
    set @x=0    -- 设置初始返回值
    
    call p2(3,5,@x);    -- 传参
    
    select @x;    -- 查询执行后的返回值

    pymysql 执行存储过程

    import pymysql
    
    conn = pymysql.connect(
        host='192.168.42.23',
        port=3306,
        user='root',
        password='123123',
        db='TestDB',
        charset='utf8'
    )
    
    cursor = conn.cursor()
    
    # row = cursor.callproc('p1')     # 调用无参数的存储过程
    # print(cursor.fetchall())        # ((1, 'ysg', '123'), (2, 'czx', '123'), (3, 'pei', '123'), (4, 'qwe', '123123')...)
    
    cursor.callproc('p2', (3, 5, 0))    # 调用有参数的存储过程
    print(cursor.fetchall())            # ((3, 'pei', '123'), (4, 'qwe', '123123'), (5, 'test', '123123'))
    print(cursor.execute('select @_p2_2=0'))    # 1
    
    cursor.close()
    conn.close()

    注意:pymysql 在调用有参数的存储过程时,cursor.callproc('p2', (3, 5, 0)) 中的值表示 @_p2_0=3,@_p2_1=5,@_p2_2=0

  • 相关阅读:
    精确覆盖DLX算法模板另一种写法
    Hdu3498-whosyourdaddy(精确覆盖模板题)
    精确覆盖DLX算法模板
    Object2Map
    Use ResourceBundle read properties file.
    Kendo UI Example(grid)
    Kendo 日期控件
    Spring mvc 中文乱码问题解决方法
    Thread communication java.util.concurrent.locks.Condition 用法(二)
    Thread communication java.util.concurrent.locks.Condition 用法(一)
  • 原文地址:https://www.cnblogs.com/ysging/p/12361354.html
Copyright © 2011-2022 走看看