Python cx_Oracle中Oracle Prepared Statement的IN子句

6
我愿意使用cx_Oracle在Python中准备好的语句来使用IN子句进行翻译。例如,查询 - select name from employee where id in ('101', '102', '103')。在Python侧,我有一个列表[101, 102, 103],我将其转换为字符串('101', '102', '103')并在Python中使用以下代码:
import cx_Oracle
ids = [101, 102, 103]
ALL_IDS = "('{0}')".format("','".join(map(str, ids)))
conn = cx_Oracle.connect('username', 'pass', 'schema')
cursor = conn.cursor()
results = cursor.execute('select name from employee where id in :id_list', id_list=ALL_IDS)
names = [x[0] for x in cursor.description]
rows = results.fetchall()

这行代码不起作用,我做错了什么吗?

4个回答

5

这个概念不被Oracle支持,而且你肯定不是第一个尝试这种方法的人!你必须:


cx_Oracle文档中有关此内容的说明在将多个值绑定到SQL WHERE IN子句一节中。 - Christopher Jones

0
只需将列表转换为元组,然后使用它格式化 SQL 字符串。
ids = [101, 102, 103]
param = tuple(ids)
results = cursor.execute("select name from employee where id IN {}".format(param))

-1
另一种选择是使用查询格式化字符串。
import cx_Oracle
ids = [101, 102, 103]
ALL_IDS = "('{0}')".format("','".join(map(str, ids)))
conn = cx_Oracle.connect('username', 'pass', 'schema')
cursor = conn.cursor()

query = """
select name from employee where id in ('{}')
""".format("','".join(map(str, ids)))

results = cursor.execute(query)
names = [x[0] for x in cursor.description]
rows = results.fetchall()


如果您的数据未经过消毒处理,这可能会成为一个巨大的安全漏洞。通常必须使用绑定变量,请参见https://cx-oracle.readthedocs.io/en/latest/user_guide/bind.html#binding-multiple-values-to-a-sql-where-in-clause。绑定变量还可以提高可扩展性和性能,但是如果查询不经常执行或变量数量经常更改,则可扩展性优势可能很小。 - Christopher Jones

-3

既然您已经创建了字符串,那就马上行动吧。这应该可以解决问题:

results = cursor.execute('select name from employee where id in ' + ALL_IDS)

2
除非您将所有值列入白名单并进行验证,否则这是一个重大的安全风险。 - Christopher Jones

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接