【问题标题】:"SELECT ... WHERE ... IN" with unknown number of parameters“SELECT ... WHERE ... IN”,参数数量未知
【发布时间】:2013-02-09 02:17:11
【问题描述】:

我正在尝试以...的形式执行查询

SELECT col2 FROM tab WHERE col1 IN (val1, val2, val3...)

...值存储在任意长度的 Python 列表/元组中。我似乎找不到“干净”的方法。

>>> db = connect(":memory:")
>>> db.execute("CREATE TABLE tab (col1 INTEGER, col2 TEXT)")
>>> db.execute("INSERT INTO tab VALUES(1,'one')")
>>> db.execute("INSERT INTO tab VALUES(2,'two')")
>>> db.execute("INSERT INTO tab VALUES(3,'three')")
>>> db.execute("INSERT INTO tab VALUES(4,'four')")
>>> db.execute("INSERT INTO tab VALUES(5,'five')")
>>> db.commit()

# Expected result
>>> db.execute("SELECT col2 FROM tab WHERE col1 IN (1,3,4)").fetchall()
[(u'one',), (u'three',), (u'four',)]

>>> vals = (1,3,4)

>>> db.execute("SELECT col2 FROM tab WHERE col1 IN (?)", vals).fetchall()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 3 supplied.

>>> db.execute("SELECT col2 FROM tab WHERE col1 IN (?)", (vals,)).fetchall()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
sqlite3.InterfaceError: Error binding parameter 0 - probably unsupported type.

>>> db.execute("SELECT col2 FROM tab WHERE col1 IN (?)", (','.join(str(val) for val in vals),)).fetchall()
[]

>>> 

现在我可以做到以下几点,(我认为……如果我错了请纠正我)保留了内置参数替换的安全性,但它仍然有点难看:

>>> db.execute("SELECT col2 FROM tab WHERE col1 IN (" + ",".join("?"*len(vals)) + ")", vals).fetchall()
[(u'one',), (u'three',), (u'four',)]
>>> 

这是我最好的选择,还是有更好的解决方法?

【问题讨论】:

标签: python sqlite


【解决方案1】:

这是您的最佳选择无需使用额外的库。我过去肯定有advocated just that technique,实际上是more than once

您也可以改用 SQLAlchemy,它会为您生成 SQL,但这需要您爬上它的学习曲线并重写您的大部分应用程序。

【讨论】:

  • 很公平,谢谢。这很难搜索,因为重要的术语是很常见的词......
【解决方案2】:

一个简单而干净的解决方案是:

vals = [1,3,4]
cursor.execute('SELECT col2 FROM tab WHERE col1 IN {}'.format(str(tuple(vals))

【讨论】:

  • 这是我试图避免的那种事情...将变量直接插入查询字符串(而不是使用参数替换)会使您面临潜在的 SQL 注入攻击。
  • 我同意,但似乎仍然没有安全的解决方案!
  • 我使用的解决方案(问题中的最后一个示例)很丑陋,但仍然保持正确的参数替换。
猜你喜欢
  • 2022-08-05
  • 2017-01-13
  • 2012-10-15
  • 2014-04-20
  • 2016-07-07
  • 1970-01-01
  • 2014-02-20
  • 2017-09-19
  • 2011-11-24
相关资源
最近更新 更多