Python SQL选择可能的NULL值

时间:2009-06-30 13:10:07

标签: python sql null

我是python的新手,遇到了我正在尝试执行的SQL查询的问题。

我正在创建一个SQL SELECT语句,该语句使用数组中的值填充,如下所示:

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

这在我在values数组中有实际值的地方工作正常。但是,在某些情况下,值中的单个条目可能设置为“无”。然后查询失败,因为“= NULL”测试不起作用,因为测试应该是IS NULL。

有一个简单的方法吗?

7 个答案:

答案 0 :(得分:3)

使用:“从testtable中选择*(a =?或a为空)和(b =?或b为空)”

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

答案 1 :(得分:1)

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

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

如果var为None,则返回“IS”,否则返回“=”。

虽然在一行中做到这一点并不是很优雅,但仅仅是为了演示:

query = "SELECT * FROM testTable WHERE a %s %s" % ( ("=","IS")[a is None], str(a) )

答案 2 :(得分:1)

如果您使用的是SQL Server,那么只要您为会话'= null'设置ANSI_NULLS,就可以进行比较。

SET ANSI_NULLS

答案 3 :(得分:0)

如果你喜欢冒险,你也可以查看SQLAlchemy。它提供了许多其他功能,它可以自动将比较转换为无法转换为IS NULL操作。

答案 4 :(得分:0)

首先,我强烈建议您不要使用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不会损害您的查询,并且应该允许更有效的查询计划。这也有一个优点,它可以在存储过程中工作,您可能无权动态构建查询字符串。

答案 5 :(得分:0)

现在已经在python sqlite3上测试了以下内容,但是它应该适用于其他数据库类型,因为它非常通用。这种方法与@MoshiBin的答案相同,但有一些补充:

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

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

为了支持空变量,您可以将第4行替换为:

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')

修改的:
最近我发现了另外两种方法也可以在这种情况下使用并使用常规的cursor.execute()语法,但是我现在没有测试过这些方法:

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

(Thx to @BillKarwin answer

或使用CASE表达式:

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

答案 6 :(得分:0)

它对我有效。

with mysqlcon.cursor() as cursor:
    sql = "SELECT * \
            FROM `books` \
            WHERE `date` is NULL"
    cursor.execute(sql)
    books = cursor.fetchall()

    return books