【发布时间】:2014-10-01 00:36:19
【问题描述】:
我在 Python 中有一个值数组,我需要在 SQL 查询的 IN 子句中使用它。数组不是固定大小的。目前我正在使用简单的字符串替换,但我更喜欢使用命名绑定变量来避免 sql 注入攻击,这样我就可以在 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 字典添加额外的参数,但感觉就像我在谷仓里做一些不应该那么困难的事情。在我更改所有代码以使用此解决方案之前,我想我会看看这里是否有人知道更“正确”的方法来做到这一点。
【问题讨论】: