繁体   English   中英

带有 IS NULL 的 Java 准备语句

[英]Java Prepared Statement with IS NULL

假设我有一个这样的 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()

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

我试过的另一个选择是:

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”选择一行?

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

所以唯一的解决方案是明确地写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";

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

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

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

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 <=> ?"

暂无
暂无

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

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