Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python SQL Select具有可能的空值_Python_Sql_Null - Fatal编程技术网

Python SQL Select具有可能的空值

Python SQL Select具有可能的空值,python,sql,null,Python,Sql,Null,我是python新手,在尝试执行SQL查询时遇到了一个问题 我正在创建一个SQL SELECT语句,该语句由数组中的值填充,如下所示: ret = conn.execute('SELECT * FROM TestTable WHERE a = ? b = ? c = ?', *values) 在值数组中有实值的情况下,这可以正常工作。但是,在某些情况下,值中的单个条目可能设置为“无”。然后查询失败,因为“=NULL”测试不起作用,因为测试应该为NULL 有没有简单的方法解决这个问题?使用:“从

我是python新手,在尝试执行SQL查询时遇到了一个问题

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

ret = conn.execute('SELECT * FROM TestTable WHERE a = ? b = ? c = ?', *values)
在值数组中有实值的情况下,这可以正常工作。但是,在某些情况下,值中的单个条目可能设置为“无”。然后查询失败,因为“=NULL”测试不起作用,因为测试应该为NULL

有没有简单的方法解决这个问题?

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


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

如果您喜欢冒险,也可以查看SQLAlchemy。它提供了一个SQL构造工具包,可以自动将“无”的比较转换为“为空”的操作。

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

("=","IS")[var is None]
如果var为None,则返回“IS”,否则返回“=”

但在一行中这样做并不十分优雅,只是为了演示:

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

如果您使用的是SQL Server,那么只要将会话“=null”的ANSI_null设置为off,比较就可以工作


首先,我要强烈警告您不要使用
SELECT*FROM tbl,其中(col=:x或col为NULL)
,因为这很可能会取消您的查询的索引资格(使用查询探查器)
SET ANSI_NULLS
也是特定数据库类型中可能不支持的内容之一

如果您的SQL方言支持
Coalesce
,那么更好的解决方案(或者至少是更通用的解决方案)是这样编写查询:

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

由于
col=col
的计算结果始终为true,因此将
NULL
传递给
:x
不会损坏您的查询,并且应该考虑到更高效的查询计划。这还有一个优点,即它可以在存储过程中工作,在存储过程中,您可能无法自由地动态构建查询字符串。

以下内容现在已经在python sqlite3上进行了测试,但是它应该可以在其他DB类型中工作,因为它非常通用。方法与@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至@BillKarwin)

或者,使用大小写表达式:

c.execute('SELECT * FROM TestTable WHERE CASE :1 WHEN NOT NULL THEN colname = :1 ELSE colname IS NULL END', {'1': a})
这对我来说很管用

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

    return books

另外,Python值
None
相当于SQL
NULL
。这是一个很好的简单解决方案,运行良好。非常感谢!