【问题标题】:Pass list as a parameter of query [duplicate]将列表作为查询参数传递[重复]
【发布时间】:2018-05-30 18:50:08
【问题描述】:

有没有办法将python列表作为pymysql中prepared statement的参数传递?

list_id = [1,2,3]
sql = "select * from table where id in (%s)"
cursor.execute(sql,(list_id,))

【问题讨论】:

  • 不。没有办法做到这一点......将一组(列表)值传递到单个绑定占位符中。准备好的语句绑定值是 标量 值。无法传递将被解释为 SQL 的语法。要执行这是一个带有绑定占位符的准备好的语句,SQL 文本需要是“SELECT * FROM table WHERE id IN (?,?,?)”,每个值都有一个单独的问号。我们可以编写代码来计算列表中值的数量,然后动态生成一条带有所需占位符数量的 SQL 语句。
  • @spencer7593 我认为这是链接问题的答案中解释的确切技术

标签: python mysql pymysql


【解决方案1】:

我会这样做。

list_id = [1,2,3]
sql = "select * from table where id in ({})".format(",".join([str(i) for i in list_id]))
print(sql)

Out[]: "select * from table where id in (1,2,3)"

如果您需要另一种运行执行的方式,这里是通过pyodbc 库执行许多游标的另一个参考。希望对您有所帮助。

cursor.executemany

executemany(sql, *params)

对每个集合执行相同的 SQL 语句 参数,返回无。单个 params 参数必须是 序列的序列,或序列的生成器。

params = [ ('A', 1), ('B', 2) ] executemany("插入到 t(name, id) values (?, ?)", params) 这将执行两次 SQL 语句, 一次使用 ('A', 1),一次使用 ('B', 2)。

【讨论】:

  • 这不是 OP 所要求的。他们想要一个可以使用IN 然后提供列表的查询。
  • 是的,转念一想,我意识到我跑题了;p 所以我修改了答案。谢谢提醒
  • 您的编辑令人困惑(什么相关性 ids executemany?)并且存在 SQL 注入的重大风险。完全没有理由在这里使用字符串格式。阅读副本对您很有用,因为如果您曾经在生产代码中执行过类似的操作,您会坦诚面对重大问题。
  • @roganjosh,我知道 SQL 注入风险。感谢您指出我的代码中的缺陷,因为我当然没有直接的数据库设计经验,所以我可能缺乏经验。我只是想帮助 OP,因为 OP 试图将一组列表传递给一个占位符,我认为可以通过将 int 元素转换为 str 并用逗号将其加入以遵守SQL 语法。
【解决方案2】:

如果您的列表只有整数,那么您必须将它们与 ',' 组合并作为字符串传递。

【讨论】:

    【解决方案3】:
    list_id = [1,2,3]
    # not working:
    list_str = ', '.join(list_id)
    # most likely:
    list_str = ', '.join(map(str, list_id))
    

    但是更好的方法是使用https://www.python.org/dev/peps/pep-0249/#paramstyle 或在上面的重复答案中提到的防止构造疯狂语句。 )

    【讨论】:

    • 它不起作用
    • pymysql 不接受逗号分隔的字符串
    • @Jean-FrançoisFabre 这也是不好的做法,因为它对 SQL 注入开放。
    • 您想构造什么 SQL 语句?
    • @EvgenyPogrebnyak 几乎可以肯定SELECT * FROM somewhere WHERE some_val IN (1, 2, 3)。我实际上认为您的查询可以工作,但这仍然是不好的做法。编辑不,它不起作用,因为您将字符串插值语法与 SQL 参数化查询混合在一起。
    猜你喜欢
    • 2019-12-09
    • 1970-01-01
    • 2015-11-07
    • 2012-08-26
    • 2019-01-02
    • 1970-01-01
    • 1970-01-01
    • 2019-07-23
    • 1970-01-01
    相关资源
    最近更新 更多