简体   繁体   English

带有 IS NULL 的 Java 准备语句

[英]Java Prepared Statement with IS NULL

Let say I have a MySQL table like this:假设我有一个这样的 MySQL 表:

VARCHAR 100 | VARCHAR 100 | VARCHAR 100 | VARCHAR 100 | VARCHAR 100 VARCHAR 100

[ ID ] [ NAME ] [ NICKNAME ] [ FAVORITE_COLOR ] [ID] [姓名] [昵称] [FAVORITE_COLOR]

1 John Johnny RED 1 约翰·约翰尼·红

2 Eric NULL GREEN 2 Eric NULL 绿色

I want to select the 2nd row where Nickname is NULL using the following prepared statement in Java:我想在 Java 中使用以下准备好的语句选择昵称为 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()

This query does not work.此查询不起作用。 The result set is empty.结果集为空。

Another option I tried is:我试过的另一个选择是:

statement.setNull(2,java.sql.Types.VARCHAR)

This also does not work and the result set is empty.这也不起作用,结果集为空。

Lastly, I tried a different SQL but its clearly wrong and returns too many rows (because it's not strict enough):最后,我尝试了一个不同的 SQL,但它显然是错误的并返回了太多行(因为它不够严格):

statement = "SELECT * FROM my_table WHERE name = ? AND (nickname IS NULL) OR (nickname = ?)"

This selects too many rows in my case.在我的情况下,这选择了太多行。

So my question is: How, using a Java PreparedStatement, can I select a row using the MySQL 'IS NULL'?所以我的问题是:如何使用 Java PreparedStatement 使用 MySQL 的“IS NULL”选择一行?

This is a well known limit of SQL databases.这是众所周知的 SQL 数据库限制。 For most databases, you must write ... WHERE field IS NULL to test for NULL values of field .对于大多数数据库,您必须编写... WHERE field IS NULL来测试field NULL 值。 Neither ... field = NULL , nor ... field = :param where :param is a parameter of a parameterized query ever match a NULL value. ... field = NULL... field = :param其中:param是参数化查询的参数都不会匹配 NULL 值。

So the only solution is to explicitely write field IS NULL is your query.所以唯一的解决方案是明确地写field IS NULL是你的查询。 Said differently you need 2 different queries, one for non null values (and only one parameter) and the other one for null values (and 2 parameter).换句话说,您需要 2 个不同的查询,一个用于非空值(只有一个参数),另一个用于空值(和 2 个参数)。

statement = "SELECT * FROM my_table WHERE name = ? AND nickname = ?";
statement = "SELECT * FROM my_table WHERE name = ? AND nickname IS NULL";

You can use the trick (beware of parentheses as explained by JBNizet)你可以使用这个技巧(注意 JBNizet 解释的括号)

statement = "SELECT * FROM my_table WHERE name = ? AND (nickname = ? OR nickname IS NULL)";

If you want to still use 2 parameters for the query asking for NULL values.如果您仍想对要求 NULL 值的查询使用 2 个参数。

https://dev.mysql.com/doc/refman/8.0/en/comparison-operators.html#operator_equal-to https://dev.mysql.com/doc/refman/8.0/en/comparison-operators.html#operator_equal-to

NULL-safe equal. NULL 安全的相等。 This operator performs an equality comparison like the = operator, but returns 1 rather than NULL if both operands are NULL, and 0 rather than NULL if one operand is NULL.此运算符执行与 = 运算符类似的相等比较,但如果两个操作数均为 NULL,则返回 1 而不是 NULL,如果一个操作数为 NULL,则返回 0 而不是 NULL。

The <=> operator is equivalent to the standard SQL IS NOT DISTINCT FROM operator. <=> 运算符等效于标准 SQL IS NOT DISTINCT FROM 运算符。

For null to work update your query to: statement = "SELECT * FROM my_table WHERE name = ? AND nickname <=> ?"为了使 null 起作用,请将您的查询更新为: statement = "SELECT * FROM my_table WHERE name = ? AND nickname <=> ?"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM