python array to sql in 子句

标签 python oracle cx-oracle

我有一个 Python 值数组,需要在 SQL 查询的 IN 子句中使用。该数组不是固定大小。目前我正在使用简单的字符串替换,但我更愿意使用命名绑定(bind)变量来避免 sql 注入(inject)攻击,这样我就可以在 SQL 查询的多个位置引用相同的变量:

我当前的代码(简化摘录):

accts = ['A123', 'B456', 'C789']
acct_list = ','.join(["'%s'" % a for a in accts])
cursor.execute('''
    SELECT A,B,C FROM SOME_TABLE WHERE ACCT_CODE IN ({alist})
    UNION SELECT A,B,C FROM OTHER_TABLE WHERE ACCT_CODE IN ({alist})
'''.format(alist=acct_list))

理想情况下,我想做这样的事情,但我知道这并不容易:

accts = ['A123', 'B456', 'C789']
cursor.execute('''
    SELECT A,B,C FROM SOME_TABLE WHERE ACCT_CODE IN (:alist)
    UNION SELECT A,B,C FROM OTHER_TABLE WHERE ACCT_CODE IN (:alist)
''', alist=accts)

到目前为止我想到的唯一解决方案是这个,但这不太理想,尤其是当我除了这个列表之外还有其他 SQL 变量时:

accts = ['A123', 'B456', 'C789']
vars = ['acct%d' % int(x+1) for x,a in enumerate(accts)]
vlist = ','.join([':%s' % v for v in vars])
parms = dict(zip(vars, accts))
sql = '''
    SELECT A,B,C FROM SOME_TABLE WHERE ACCT_CODE IN ({vlist})
    UNION SELECT A,B,C FROM OTHER_TABLE WHERE ACCT_CODE IN ({vlist})
'''.format(vlist=vlist)
cursor.execute(sql, parms)

上面的最后一个代码块将允许我做我需要做的所有事情,包括向查询和 parms 字典添加额外的参数,但感觉就像我在谷仓里转来转去做一些不应该那么困难的事情。在我更改所有代码以使用此解决方案之前,我想看看这里是否有人知道更“正确”的方法来执行此操作。

最佳答案

我没有将它用于“in”子句,但对于具有可变数量项的插入语句,我确实使用了 ?标记乘以列表中的元素数:

cur.execute("INSERT INTO my_table("+','.join([x for x in field_list])+") VALUES("+"?,"*(len(field_list)-1)+"?)", insert_list)

因此实际的 python 插入字符串如下所示:

cur.execute('''INSERT INTO my_table(a,b,c,d,e,f,g,h,i,j) VALUES(?,?,?,?,?,?,?,?,?,?)''', insert_list)

关于python array to sql in 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25188112/

相关文章:

python - cx_Oracle : How do I iterate over a result set?

python - PYSPARK:CX_ORACLE.InterfaceError:不是查询

python - 为什么这个 Python 方法会泄漏内存?

python - 大文本文件的并行计算

python - PyQt5 图像和 QGridlayout

java - 错误 4956 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper : ORA-00923: FROM keyword not found where expected

python - cx_Oracle.OracleCursor 的类型验证

python - 无法在 jupyter 实验室中导入 pymc3

sql - Oracle 合并列给出错误

java - 未在应用程序的数据库列中设置默认值