我是python的新手,我想做一个类似的查询:
_c.execute('select * from cases where bi = ? and age = ? and
shape = ? and margin = ? and density = ?',(obj['bi'],
obj['age'], obj['margin'], obj['density']))
当某些参数为None
(例如obj['bi'] = None
(时,查询将在bi = 'None'
时搜索该行。但我希望它在以下时间搜索行:'bi is NULL'
一个可能的解决方案是在if-else序列中逐个验证参数的值。例如:
query = 'select * from cases where'
if obj['bi'] is None:
query += ' bi is null'
else:
query += ' bi = ' + str(obj['bi']) + ' and '
...
# do the same if-else for the other parameters
...
_c.execute(query)
但是,在我看来,这并不是最好的解决方案。问题是,给定问题的最佳解决方案是什么,以及如何避免SQL注入。
好吧,在启动一个python REPL并玩了一点之后,它比我想象的要简单。Python-sqlite绑定将PythonNone
转换为SQLNULL
,而不是像您的问题中那样转换为字符串'None'
。在SQL中,=
与NULL
的值不匹配,但IS
会匹配。所以…
给定一个表foo
,看起来像:
a | b
--------------
NULL | 1
Dog | 2
操作:
c = conn.cursor()
c.execute('SELECT * FROM foo WHERE a IS ?', (None,))
print(c.fetchone())
将返回(NULL, 1)
行,并且
c.execute('SELECT * FROM foo WHERE a IS ?', ('Dog',))
print(c.fetchone())
将返回CCD_ 13行。
换句话说,在查询中使用IS
而不是=
。