假设我有一个像这样的MySQL表:
VARCHAR 100 | VARCHAR 100 | VARCHAR 100
[ID] [NAME] [NICKNAME] [FAVORITE_COLOR]
1 John Johnny RED
2 Eric NULL GREEN
我想在Java中使用以下预准备语句选择Nickname为NULL的第二行:
statement = "SELECT * FROM my_table WHERE name = ? AND nickname = ?"
prepared = connection.prepareStatement(statement)
prepared.setString(1, "Eric")
prepared.setString(2, null)
result = prepared.executeQuery()
此查询不起作用。结果集为空。
我尝试的另一个选择是:
statement.setNull(2,java.sql.Types.VARCHAR)
这也不起作用,结果集为空。
最后,我尝试了一个不同的SQL,但它显然是错误的,并返回太多行(因为它不够严格):
statement = "SELECT * FROM my_table WHERE name = ? AND (nickname IS NULL) OR (nickname = ?)"
在我的情况下,这会选择太多行。
所以我的问题是:如何使用Java PreparedStatement,我可以使用MySQL选择一行' IS NULL'
答案 0 :(得分:2)
这是众所周知的SQL数据库限制。对于大多数数据库,您必须编写anchor
来测试... WHERE field IS NULL
的NULL值。 field
和... field = NULL
其中... field = :param
是参数化查询的参数,都不匹配NULL值。
所以唯一的解决方案是明确地写:param
是你的查询。换句话说,您需要2个不同的查询,一个用于非空值(并且只有一个参数),另一个用于空值(和2个参数)。
field IS NULL
你可以使用这个技巧(谨防JBNizet解释的括号)
statement = "SELECT * FROM my_table WHERE name = ? AND nickname = ?";
statement = "SELECT * FROM my_table WHERE name = ? AND nickname IS NULL";
如果您仍想使用2个参数来查询请求NULL值。
答案 1 :(得分:0)
https://dev.mysql.com/doc/refman/8.0/en/comparison-operators.html#operator_equal-to
NULL安全等于。该运算符执行与=运算符类似的相等比较,但是如果两个操作数均为NULL,则返回1而不是NULL,如果一个操作数为NULL,则返回0而不是NULL。
<=>运算符等效于标准的SQL IS NOT DISTINCT FROM运算符。
为使null有效,请将您的查询更新为:
statement = "SELECT * FROM my_table WHERE name = ? AND nickname <=> ?"