假设我有一个这样的MySQL表:
VARCHAR 100|VARCHAR 100|VARCHAR 100
[ ID ] [名称] [昵称] [收藏夹_颜色]
1约翰·约翰尼·雷德
2 Eric空绿色
我想使用以下Java预处理语句选择Nickname为NULL的第2行:
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'选择行?
3条答案
按热度按时间jdzmm42g1#
这是SQL数据库的一个众所周知的限制。对于大多数数据库,必须编写
... WHERE field IS NULL
来测试field
的NULL值。... field = NULL
和... field = :param
(其中:param
是参数化查询的参数)都不匹配NULL值。因此,唯一的解决方案是在查询中显式地写入
field IS NULL
。换句话说,你需要两个不同的查询,一个用于非空值(只有一个参数),另一个用于空值(和2个参数)。你可以使用这个技巧(小心括号,如JBNizet所解释的)
如果您仍然希望使用2个参数来查询NULL值。
pbwdgjma2#
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 <=> ?"
pkbketx93#
@John安德森,你验证了一个答案,实际上不起作用。让我解释一下。
让我们收回经过验证的比较,并关注第二个WHERE子句:
在
? = 'something'
的情况下,你有:所以你总是得到nickname为NULL的行,不管
?
的值是什么(当?
实际上不是NULL时的副作用)。实际上,在?
不为NULL的情况下,您总是会得到NULL行和您要查找的行。下面是一种实际操作技巧的方法(亲自测试):
2个主要病例的详细信息:
?
是NULL
:所以你得到的就是nickname为NULL的行。
?
='something'
:所以你确切地得到了nickname = 'something'的行。