【问题标题】:Using a WHERE ___ IN ___ statement使用 WHERE ___ IN ___ 语句
【发布时间】:2012-12-24 02:25:27
【问题描述】:

我正在尝试弄清楚如何正确使用 WHERE _ IN _ 语句

定义:

c.execute('''CREATE TABLE IF NOT EXISTS tab (
    _id integer PRIMARY KEY AUTOINCREMENT,
    obj text NOT NULL
    ) ;''')

我正在尝试做这样的事情:

list_of_vars=['foo','bar']
statement="SELECT * FROM tab WHERE obj IN (?)"
c.execute(statement,"'"+"','".join(list_of_vars)+"'")

另外,我也试过这个,它直接评估为上述

statement="SELECT * FROM tab WHERE obj IN (?)"
c.execute(statement,"'foo','bar'")

我得到的错误是:

sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 9 supplied

这给了我一个错误。当我这样做时,它可以工作,但不建议这样做,因为它容易受到 SQL 注入攻击。

statement="SELECT * FROM tab WHERE obj IN ("+"'"+"','".join(statement)+"'"+")

【问题讨论】:

    标签: python sql sqlite


    【解决方案1】:

    您需要创建足够的参数来匹配您的变量列表:

    statement = "SELECT * FROM tab WHERE obj IN ({0})".format(', '.join(['?'] * len(list_of_vars)))
    c.execute(statement, list_of_vars)
    

    请注意,您将list_of_vars 作为参数值列表传入。使用', '.join(),我们生成一个由逗号分隔的? 字符组成的字符串,然后使用.format() 将其插入到语句中。

    对于一长串变量,使用临时表来保存这些值可能更有效,然后对临时表使用 JOIN 而不是带有绑定参数的 IN 子句。

    【讨论】:

    • +1。但是为什么不只是 '?' * len(list_of_vars) 而不是生成器表达式呢?
    • @abarnet:有点天赋?我本来打算timeit看看它除了个人风格之外是否还有其他用途,但我暂时分心了。
    • 好吧,这适用于简单的测试用例,但不是我真正做的更高级的测试用例......叹息。尽管如此,它还是向前迈出了一步!
    • @Martijn Pieters:我们不要求我们的员工穿着 37 件风衣。
    • @abarnert:很快timeit 之后我将其切换为.join(['?' * len(list_of_vars)]),因为在.join() 中使用列表比生成器更快。才华横溢!
    【解决方案2】:

    仅供参考,使用 MySQL 用户的 pymysql。

    query ="SELECT * FROM tab WHERE obj IN %s"
    cursor.execute(query, (['foo','bar'],))
    
    same as
    
    cursor.execute(query, (list_of_var,)) 
    

    我不确定 sqlite3, 这可能有效,

    query ="SELECT * FROM tab WHERE obj IN ?"
    cursor.execute(query, (['foo','bar'],)) 
    or
    cursor.execute(query, (list_of_vars,))  
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-26
      • 2015-03-22
      • 2016-05-13
      • 1970-01-01
      • 2013-10-16
      • 2016-04-05
      • 2010-12-23
      相关资源
      最近更新 更多