Python SQL选择可能的NULL值
我是python的新手,并且遇到了一个我试图执行的SQL查询的问题。Python SQL选择可能的NULL值
我创建的填充值从数组如下SQL SELECT语句:
ret = conn.execute('SELECT * FROM TestTable WHERE a = ? b = ? c = ?', *values)
该工程确定在那里我有数值数组中的实际值。但是,在某些情况下,值中的单个条目可能设置为无。查询然后失败,因为“= NULL”测试不起作用,因为测试应该是IS NULL。
有没有简单的方法呢?
使用:“从TestTable的选择*其中(A =或为空?)和(b =或b为空?)”
这将选择情况下,一所提供的值完全匹配,将包括列中的空值 - 如果这是你想要的。
另外,Python值`None`等价于SQL`NULL`。 – 2009-06-30 14:04:58
如果你觉得冒险,你也可以看看SQLAlchemy。它在很多其他的东西中提供了一个SQL构建工具包,可以自动将比较转换为无到IS NULL操作。
您可以随时使用三元运算为 'IS' 切换 '=':
("=","IS")[var is None]
将返回 “IS” 如果VAR是无与 “=”,否则。
这不是很高雅做的这一条线,虽然,但只是为了证明:
query = "SELECT * FROM testTable WHERE a %s %s" % (("=","IS")[a is None], str(a))
首先,我会强烈提醒您不要使用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
不会损坏您的查询,并且应该允许更有效的查询计划。这也有一个好处,它可以在存储过程内工作,在那里你可能没有动态构建查询字符串的自由。
以下是在python sqlite3上测试的,但它应该可以在其他数据库类型中使用,因为它非常通用。这个方法和@MoshiBin的答案一样,有一些增加:
这里是使用光标的表单。执行()常规语法,所以在使用这种形式,不支持空变量:
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')
Finaly如果一个变量可以包含一个单引号本身,还需要加倍逃脱它:
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 answer)
,或者使用CASE表达式:
c.execute('SELECT * FROM TestTable WHERE CASE :1 WHEN NOT NULL THEN colname = :1 ELSE colname IS NULL END', {'1': a})
这是一个很好的简单解决方案,工作正常。非常感谢! – JamieH 2009-06-30 14:33:36