在Python中编写动态SQL语句

个人经验总结,有问题请指出

目录

  • 0x00 前期准备
  • 0x01 占位符方式(推荐)
  • 0x02 字符串格式化

0x00 前期准备

import pymysql
import datetime
conn = pymysql.connect('localhost', 'root', '****', 'sakila')
cur = conn.cursor()

# 这里准备编写sql语句

cur.close()
conn.close()

0x01 占位符方式(推荐)

aid = 1
dt = datetime.datetime(2014, 9, 25, 22, 30, 27)
sql = """SELECT * FROM address WHERE address_id = %s AND last_update = %s"""

cur.execute(sql, (aid, dt))  # 多个占位符的话用tuple或list
print(cur.fetchall())
param = {'dt': datetime.datetime(2014, 9, 25, 22, 30, 27)}
sql = """SELECT * FROM address WHERE address_id = 1 AND last_update = %s"""

cur.execute(sql, parma.get('dt'))  # 一个占位符,只传相应的值或变量即可
print(cur.fetchall())

表名不可使用占位符,如需动态表名,请先使用format格式化sql语句。以下是分析,可以跳过。

# 错误示范
tb = 'address'
aid = 1
dt = datetime.datetime(2014, 9, 25, 22, 30, 27)
sql = """SELECT * FROM %s WHERE address_id = %s AND last_update = %s"""  # 表名占位符
cur.execute(sql, (tb, aid, dt))  # 此处会报错pymysql.err.ProgrammingError,提示sql语句有问题
print(cur.fetchall())

我们打断点在cur.execute(sql, (tb, aid, dt)),DEBUG进入execute方法,F8逐行执行,会有如下图在Python中编写动态SQL语句_第1张图片
由图可见,它在表名上加了引号,故sql语法错误。
如需动态表名,请先使用format格式化sql语句。

# 正确示范
tb = 'address'
aid = 1
dt = datetime.datetime(2014, 9, 25, 22, 30, 27)
# 因为%s已经用作占位符,我们不能再用%s来格式化表名,只能用format
sql = """SELECT * FROM {} WHERE address_id = %s AND last_update = %s""".format(tb) 
cur.execute(sql, (aid, dt))
print(cur.fetchall())

0x02 字符串格式化

  • %
tb = 'address'
aid = 1
dt = datetime.datetime(2014, 9, 25, 22, 30, 27)
# 注意last_update列加了引号
sql = """SELECT * FROM %s WHERE address_id = %d AND last_update = '%s' """ % (tb, aid, dt)
cur.execute(sql)
print(cur.fetchall())
param = {
    'tb': 'address',
    'aid': 1,
    'dt': datetime.datetime(2014, 9, 25, 22, 30, 27),
}
# 注意last_update列加了引号
sql = """SELECT * FROM %(tb)s WHERE address_id = %(aid)d AND last_update = '%(dt)s' """ % param
cur.execute(sql)
print(cur.fetchall())
  • format()
tb = 'address'
aid = 1
dt = datetime.datetime(2014, 9, 25, 22, 30, 27)
# 注意last_update列加了引号
sql = """SELECT * FROM {} WHERE address_id = {} AND last_update = '{}'""".format(tb, aid, dt)

# 参数已经是一个tuple或者list时,且位置一一对应
# param = (tb, aid, dt)
# sql = """SELECT * FROM {} WHERE address_id = {} AND last_update = '{}'""".format(*param)

# 参数已经是一个tuple或者list时,但位置不对或只需其中某些参数
# sql = """SELECT * FROM {1[0]} WHERE address_id = {0[0]} AND last_update = '{0[1]}'""".format((aid, dt)(tb,))
cur.execute(sql)
print(cur.fetchall())
param = {
    'tb': 'address',
    'aid': 1,
    'dt': datetime.datetime(2014, 9, 25, 22, 30, 27),
}
# 注意last_update列加了引号
sql = """SELECT * FROM {0[tb]} WHERE address_id = {0[aid]} AND last_update = '{0[dt]}' """.format(param)
cur.execute(sql)
print(cur.fetchall())
  • +(勿用)
tb = 'address'
aid = 1
dt = datetime.datetime(2014, 9, 25, 22, 30, 27)
sql = """SELECT * FROM """+tb+""" WHERE address_id = """+str(aid)+""" AND last_update = '"""+dt.strftime('%Y-%m-%d %H:%M:%S')+"'"
cur.execute(sql)
print(cur.fetchall())

你可能感兴趣的:(mysql,mysql,python)