大佬教程收集整理的这篇文章主要介绍了如何在 Python SQLite 中安全地使用 IN 命令?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
有没有办法在 Python 中动态使用 sqlite IN
命令而不提供确切的占位符数量?
例如,假设我正在尝试获取:
SELECT
*
FROM myTable
WHERE someCol IN (1,3,4,7,9)
在 Python 中,占位符是至少长度为 1 的元组,但我不确定如何(甚至如果是可能的)将它们与 IN
命令一起使用。我试过纯元组、字符串元组和纯字符串,自由的和封闭的,都无济于事:
In [1]: import sqlite3
...: conn = sqlite3.connect(':memory:')
...: cur = conn.cursor()
...: l = [(i,chr(i+64)) for i in range(1,11)]
...: cur.execute('create table myTable (someCol IntegeR,char TEXT)')
...: cur.executemany('INSERT INTO myTable VALUES(?,?)',l)
...: conn.commit()
In [2]: tup = ((1,9),)
...: cur.execute('SELECT * FROM myTable WHERE someCol IN ?',tup)
OperationalError TraceBACk (most recent call last)
<ipython-input-2-195e99af7b4f> in <module>
----> 1 cur.execute('SELECT * FROM myTable WHERE someCol IN ?',tup).fetchall()
OperationalError: near "?": Syntax error
In [3]: cur.execute('SELECT * FROM myTable WHERE someCol IN (?)',tup).fetchall()
---------------------------------------------------------------------------
InterfaceError TraceBACk (most recent call last)
<ipython-input-2-a6c2d28cce18> in <module>
----> 1 cur.execute('SELECT * FROM myTable WHERE someCol IN (?)',tup).fetchall()
InterfaceError: Error binding parameter 0 - probably unsupported type.
In [4]: tups = tuple(str(i) for i in tup)
...: cur.execute('SELECT * FROM myTable WHERE someCol IN ?',tups)
OperationalError TraceBACk (most recent call last)
<ipython-input-3-195e99af7b4f> in <module>
----> 1 cur.execute('SELECT * FROM myTable WHERE someCol IN ?',tups).fetchall()
OperationalError: near "?": Syntax error
In [5]: # Empty List due to trying to fetch a someCol String value of "(1,9)"
...: cur.execute('SELECT * FROM myTable WHERE someCol IN (?)',tups).fetchall()
Out[5]: []
In [6]: stup = (','.join(str(i) for i in tup[0]),stup)
OperationalError TraceBACk (most recent call last)
<ipython-input-5-195e99af7b4f> in <module>
----> 1 cur.execute('SELECT * FROM myTable WHERE someCol IN ?',stup).fetchall()
OperationalError: near "?": Syntax error
In [7]: # Empty List due to trying to fetch a someCol String value of "1,9"
...: cur.execute('SELECT * FROM myTable WHERE someCol IN (?)',stup).fetchall()
Out[7]: []
我知道如果我提供 cur.execute('SELECT * FROM myTable WHERE someCol IN (?,?,tup[0]).fetchall()
我会得到想要的结果,但那是因为我事先知道 tup[0]
的长度并相应地调整了光标。但是,这会在我无法预料的应用程序上崩溃。
我几乎可以肯定这在 Python 中实际上是不可行的,但我想知道为什么会这样并且应该这样?
sqlite 不支持其他数据库支持的序列占位符。
要解决此问题,您只需根据需要按序列生成尽可能多的单个占位符。通过像:'(' + ','.join('?'*len(v)) + ')'
您可以将所有值连接到逗号分隔的字符串中:
tup = (1,3,4,7,9)
s = ",".join(str(i) for i in tup)
然后使用运算符 LIKE
而不是 IN
:
sql = "SELECT * FROM myTable WHERE ',' || ? || ',' LIKE '%,' || someCol || ',%';"
cur.execute(sql,(s,)).fetchall()
这样你只需要 1 个占位符。
,由于参数列表不能具有相同的长度,您必须使用字符串格式来构建正确数量的参数标记检查此答案here
cur.execute("SELECT * FROM myTable WHERE someCol IN ({seq})".format( seq=','.join(['?']*len(tup[0]))),tup[0]).fetchall()
以上是大佬教程为你收集整理的如何在 Python SQLite 中安全地使用 IN 命令?全部内容,希望文章能够帮你解决如何在 Python SQLite 中安全地使用 IN 命令?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。