【问题标题】:python array to sql in clausepython数组到sql in子句
【发布时间】: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 字典添加额外的参数,但感觉就像我在谷仓里做一些不应该那么困难的事情。在我更改所有代码以使用此解决方案之前,我想我会看看这里是否有人知道更“正确”的方法来做到这一点。

【问题讨论】:

    标签: python oracle cx-oracle


    【解决方案1】:

    我没有将它用于“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)
    

    【讨论】:

    • 与我上面的第三个示例基本相同,带有数字位置参数。出于同样的原因,它有效,但并不理想。我将改进我的任务以更好地解释我的问题。
    猜你喜欢
    • 1970-01-01
    • 2013-07-29
    • 2013-08-06
    • 2010-09-25
    相关资源
    最近更新 更多