代码之家  ›  专栏  ›  技术社区  ›  JamieH

Python SQL选择,可能为NULL值

  •  4
  • JamieH  · 技术社区  · 17 年前

    ret = conn.execute('SELECT * FROM TestTable WHERE a = ? b = ? c = ?', *values)
    

    7 回复  |  直到 17 年前
        1
  •  1
  •   John Hunter    17 年前
        2
  •  3
  •   blispr    17 年前

    使用:“从测试表中选择*,其中(a=?或a为空)和(b=?或b为空)”

    这将选择a与提供的值完全匹配的情况,并在列中包含空值——如果这是您想要的。

        3
  •  1
  •   MoshiBin    17 年前

    您始终可以使用三元运算符将“=”切换为“IS”:

    ("=","IS")[var is None]
    

    不过,用一句话来表达这一点并不十分优雅,而只是为了展示:

    query = "SELECT * FROM testTable WHERE a %s %s" % ( ("=","IS")[a is None], str(a) )
    
        4
  •  0
  •   Ants Aasma    17 年前

        5
  •  0
  •   Michael Hays    15 年前

    SELECT * FROM tbl WHERE (col = :x OR col IS NULL) SET ANSI_NULLS 也是您的特定数据库类型中可能不支持的内容之一。

    更好的解决方案(或至少是更通用的解决方案)是,如果您的SQL方言支持 Coalesce

    SELECT * FROM tbl WHERE col = COALESCE(:x, col)
    

    自从 col = col 将始终评估为true,传递 NULL :x 不会损坏您的查询,并且应该允许更有效的查询计划。这也有一个优点,即它可以在存储过程中工作,在那里您可能没有动态构建查询字符串的自由。

        6
  •  0
  •   Community Mohan Dere    9 年前

    到目前为止,以下内容已经在python-sqlite3上进行了测试,但它应该适用于其他DB类型,因为它非常通用。方法与@MoshiBin的回答相同,但有一些补充:

    以下是使用cursor.execute()常规语法的表单,因此使用此表单时不支持null变量:

    import sqlite3
    conn = sqlite3.connect('mydbfile.db')
    c = conn.cursor()
    c.execute('SELECT * FROM TestTable WHERE colname = ?', (a, ))
    

    request = 'SELECT * FROM TestTable WHERE colname %s' % ('= ' + str(a) if a else 'IS NULL')
    c.execute(request)
    

    除此之外,如果变量为文本类型,还需要包含引号:

    request = "SELECT * FROM TestTable WHERE colname %s" % ("= '" + a + "'" if a else 'IS NULL')
    

    最后,如果一个变量本身可以包含一个引号,你还需要通过加倍来转义它:

    request = "SELECT * FROM TestTable WHERE colname %s" % ("= '" + a.replace("'", "''") + "'" if a else 'IS NULL')
    

    :

    c.execute('SELECT * FROM TestTable WHERE colname = :1 OR (:1 IS NULL AND colname IS NULL)', {'1': a})
    

    (感谢@BillKarwin answer )

    c.execute('SELECT * FROM TestTable WHERE CASE :1 WHEN NOT NULL THEN colname = :1 ELSE colname IS NULL END', {'1': a})