【问题标题】:JDBC setNull() vs. Oracle "is null" produce different resultsJDBC setNull() 与 Oracle "is null" 产生不同的结果
【发布时间】:2012-06-12 04:58:48
【问题描述】:

我正在 JDBC 中针对 Oracle 11g 数据库进行 PreparedStatement 查询,发现传递空参数的结果与在查询本身中定义“为空”不同。

例如,这个查询:

String sql = "SELECT col1 FROM tbl WHERE col2 = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setNull(1, java.sql.Types.INTEGER);
ps.execute();

与此查询不同:

String sql = "SELECT col1 FROM tbl WHERE col2 is null";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setNull(1, java.sql.Types.INTEGER);
ps.execute();

我很好奇为什么会这样,以及如何避免定义两个单独的 SQL 语句来涵盖“col2 = value”和“col2 is null”两种情况。

【问题讨论】:

  • 我似乎找不到比详细答案here 更简洁的方法来解决这个问题,答案是“WHERE col2 = ? OR (col2 IS NULL AND ? IS NULL)”。

标签: java oracle jdbc null


【解决方案1】:

这与Java无关,真的,这就是NULL在Oracle中的工作方式。

当与任何事物(甚至是 NULL)相比时,NULL 始终为 false,您必须使用 IS NULL。

这也不会返回任何行:

SELECT col1 FROM tbl WHERE col2 = NULL

甚至

SELECT col1 FROM tbl WHERE NULL = NULL

【讨论】:

  • 有没有办法在单个 SQL 语句中有条件地表达这一点?
  • 您的意思是,如何在不更改 SQL 语句的情况下使其在 Oracle 和另一个数据库中工作,或者如何编写一个语句来查找空值或非空值?
  • 如何编写一条语句,根据参数输入查找空值或非空值。添加“WHERE col2 = ? OR (col2 IS NULL AND ? IS NULL)”似乎是最明智的选择,要求我提供两次变量比定义和维护两个单独的查询更可取。有没有更好的选择?
  • @peterporter:这可能是“最好的”单一 SQL。但是您应该在 Java 中拆分这两种情况并发出单独的 SQL 以获得更好的性能(因为访问路径会有所不同,具体取决于您是否需要 IS NULL)。
  • @Thilo 感谢您的建议。但是,在这种情况下,我相信未来的开发人员更有可能不正确地更新这两个查询,而不是明显地影响性能。当然,在其他情况下,性能与维护之间的权衡是可取的。
【解决方案2】:

我相信ps.setNull(1, java.sql.Types.INTEGER) 用于插入 NULL 数据值到数据库中。

如果您在 sql 查询中搜索 NULL 数据值,则应使用 IS NULL

毕竟,col2 = NULL 也行不通,因为您无法使用 = 比较 NULL 的值

【讨论】:

  • 如果我想在一种情况下搜索 NULL 或在另一种情况下搜索非 null 值,但我想根据输入参数这样做?
  • 使用 if-else 语句。 if (value == null) { // 使用这个 SQL 查询 } else { // 使用另一个 SQL 查询 }
  • 我试图避免多次定义查询,因为它是一个更复杂的查询,重新定义它会增加未来的维护问题。沿着“WHERE col2 = ? OR (col2 IS NULL AND ? IS NULL)”的行向查询添加逻辑应该可以解决问题。
【解决方案3】:

如果你确定使用Oracle数据库那么你可以使用这个语句,它也会接受NULL等于NULL:

select col1 from tbl where decode(col2, ?, 1, 0)=1

不是很可读,但比上面的表达式更好。此外,您避免为准备好的语句提供两次相同的值。 在 Oracle 11 或 12 上为我工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-11
    • 1970-01-01
    • 1970-01-01
    • 2015-04-24
    • 1970-01-01
    • 2019-01-26
    • 1970-01-01
    相关资源
    最近更新 更多