如何在不从 OracleDB 获取“预期数字但已获得二进制”的情况下查询 Long 值中的 null?

2022-09-03 13:56:37

我正在使用JPQL,并希望在Long字段中查询空值。但我总是得到一个ORA-00932:不一致的数据类型:预期的数字得到二进制。正如我所看到的,有很多人对此有疑问,但是有人对此有解决方法吗?

例如,这是查询,稍后我将id设置为.这在更复杂的查询中用于筛选目的,因此在我们的例子中,null 意味着忽略列上的筛选器。"SELECT a FROM Auftrag a WHERE :id is null OR a.id = :id"setParameter("id", null)

有人有想法吗?

亲切问候!


答案 1

我不知道JPQL的细节,也不知道Oracle如何处理查询的WHERE条件。但我敢打赌,您的 WHERE 条件的第二部分并没有完全被忽略,这导致了问题。除了明显不一致的数据类型之外,像这样的条件可能不会计算为TRUE或FALSE,而是NULL(至少在PostgreSQL上会发生这种情况)。a.id = NULLsome_value = NULL

编辑
对于您的特定用例,组合条件在PostgreSQL上仍按预期工作。但是在另一个上下文中,即使为 null,您也不会获得任何行。因此,我认为为了健壮且易于理解的代码,在任何情况下都应该避免使用这样的表达式。
结束编辑:id IS NULL OR a.id = NULLsome_value = NULLsome_valuesome_value = NULL

您也许可以在 JPQL 中解决此问题

SELECT a FROM Auftrag a WHERE :id is null OR a.id = COALESCE(:id, -1)

至少这在原生Hibernate HQL中是可能的。在本例中,WHERE 条件的第二部分计算结果为 FALSE,如果为 null,但整个 WHERE 条件的计算结果为 TRUE,这是您想要的。:id

但对于动态筛选查询,更好的方法是使用 JPA 2.0 条件 API,并且仅当参数不为 null 时才在查询中包含该参数。同样,我不知道JPA标准的细节,但是对于本机Hibernate标准,这将是:id

public List<Auftrag> findByFilter(Long id) { 
  Criteria criteria = session.createCriteria(Auftrag.class);
  if (id != null) {
    criteria.add(Restrictions.eq("id", id));
  } // if
  return criteria.list();
}

希望有所帮助。


答案 2

在Oracle(12)中,我发现了一个使用TO_NUMBER的解决方法:

SELECT a FROM Auftrag a WHERE :id is null OR a.id = TO_NUMBER(:id)

推荐