带有 IS NULL 的 Java 准备语句

Joh*_*son 5 java mysql prepared-statement

假设我有一个这样的 MySQL 表:

VARCHAR 100 | VARCHAR 100 | VARCHAR 100

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

1 约翰·约翰尼·红

2 Eric NULL 绿色

我想在 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()
Run Code Online (Sandbox Code Playgroud)

此查询不起作用。结果集为空。

我试过的另一个选择是:

statement.setNull(2,java.sql.Types.VARCHAR)
Run Code Online (Sandbox Code Playgroud)

这也不起作用,结果集为空。

最后,我尝试了一个不同的 SQL,但它显然是错误的并返回了太多行(因为它不够严格):

statement = "SELECT * FROM my_table WHERE name = ? AND (nickname IS NULL) OR (nickname = ?)"
Run Code Online (Sandbox Code Playgroud)

在我的情况下,这选择了太多行。

所以我的问题是:如何使用 Java PreparedStatement 使用 MySQL 的“IS NULL”选择一行?

Ser*_*sta 3

这是 SQL 数据库的一个众所周知的限制。对于大多数数据库,您必须编写... WHERE field IS NULL测试 的 NULL 值field。参数化查询的参数... field = NULL、 和... field = :paramwhere都不匹配 NULL 值。:param

因此,唯一的解决方案是显式写入field IS NULL您的查询。换句话说,您需要 2 个不同的查询,一个用于非空值(且只有一个参数),另一个用于空值(和 2 个参数)。

statement = "SELECT * FROM my_table WHERE name = ? AND nickname = ?";
statement = "SELECT * FROM my_table WHERE name = ? AND nickname IS NULL";
Run Code Online (Sandbox Code Playgroud)

您可以使用这个技巧(请注意 JBNizet 所解释的括号)

statement = "SELECT * FROM my_table WHERE name = ? AND (nickname = ? OR nickname IS NULL)";
Run Code Online (Sandbox Code Playgroud)

如果您仍想对要求 NULL 值的查询使用 2 个参数。

  • 或者您可以使用空安全运算符“<=>”。 (4认同)