将列表作为查询参数传递[重复]
Posted
技术标签:
【中文标题】将列表作为查询参数传递[重复]【英文标题】: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 我认为这是链接问题的答案中解释的确切技术
【参考方案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 参数化查询混合在一起。以上是关于将列表作为查询参数传递[重复]的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在 JDBC 中执行“字段 IN 列表”查询,并将列表作为参数传递?
传递给 onclick 函数的 blazor 变量参数 [重复]