Python准备语句。 SELECT IN的问题

时间:2011-06-02 15:15:44

标签: python mysql sql prepared-statement

我在Python中使用准备好的语句遇到了问题,到目前为止还无法解决。

应该执行的查询是例如:

 SELECT md5 FROM software WHERE software_id IN (1, 2, 4)

所以我尝试执行这样的查询:

software_id_string = "(2, 3, 4)"
cursor.execute("SELECT md5 FROM software WHERE software_id IN %s", 
                software_id_string)

问题是在字符串中添加了' - > '(2,3,4)',以便查询将是:

SELECT md5 FROM software WHERE software_id IN ''(2, 3, 4)''

我也试过像这样重建脚本:

software_id_string = " 1 OR software_id = 2"
cursor.execute("SELECT md5 FROm software WHERE software_id = %s", 
              software_id_string)

这仅适用于将提交的第一个id(在本例中为1),因为OR部分不会作为SQL语句进行处理......

是否有可能解决准备好的陈述中的问题?

3 个答案:

答案 0 :(得分:6)

参数列表中的每个项目都需要一个占位符 您可以使用字符串操作来完成该部分:

  1. 为每个参数创建一个%s,然后
  2. 用逗号加入这些。
  3. 在下一步中,您可以按照DB-API documentation中的建议将两个参数传递给execute()

    software_id_string = (1,2,4)
    qry = '''SELECT md5 
               FROM software 
              WHERE software_id IN (%s)''' % ','.join(['%s']*len(software_id_string))
    # // 'SELECT md5 FROM software WHERE software_id IN (%s,%s,%s)'
    cursor.execute(qry, software_id_string)
    

答案 1 :(得分:2)

我建议创建一个类型转换器来显式处理IN子句。这是psycopg2模块处理它的方式:

from MySQLdb.converters import conversions

class SQL_IN(object):
    def __init__(self, seq):
        self.seq = seq

    @classmethod
    def escape(cls, obj, d):
        return '(' + ','.join((d[type(o)](o, d) for o in obj.seq)) + ')'

# add this before you call MySQLdb.connect()
conversions[SQL_IN] = SQL_IN.escape

真实的例子:

db = MySQLdb.connect()
cursor = db.cursor()

SQL = "SELECT * FROM emp WHERE emp_id IN %s"
in_values = (1, 2, 3)
cursor.execute(SQL, (SQL_IN(in_values),))
print cursor._last_executed
print cursor.fetchall()

SQL = "SELECT * FROM emp WHERE name IN %s"
in_values = ("bob", "fred")
cursor.execute(SQL, (SQL_IN(in_values),))
print cursor._last_executed
print cursor.fetchall()

输出:

SELECT * FROM emp WHERE emp_id IN (1,2,3)
((1L, 'bob'), (2L, 'larry'), (3L, 'fred'))
SELECT * FROM emp WHERE name IN ('bob','fred')
((1L, 'bob'), (3L, 'fred'))

答案 2 :(得分:0)

你想要

cursor.execute("SELECT md5 FROM software WHERE software_id IN %s" % software_id_string)

即。 a%而不是逗号