如何在不获取OracleDB的“预期NUMBER但得到BINARY”的情况下查询Long值中的null?

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

例如,这是查询"SELECT a FROM Auftrag a WHERE :id is null OR a.id = :id" ,稍后我用setParameter("id", null)设置id。这用于更复杂的查询过滤目的,所以null在我们的例子中意味着忽略列上的filter。

有想法的人吗?

亲切的问候!

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

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

您可以在JPQL中解决此问题

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

至少这可以使用原生Hibernate HQL。 在这种情况下,WHERE条件的第二部分求值为FALSE if :id为null但整个WHERE条件的计算结果为TRUE,这就是你想要的。

但是对于动态过滤查询,更好的方法是使用JPA 2.0 Criteria API,并且只有在它不为null时才在查询中包含:id参数。 同样,我不知道JPA Criteria的具体细节,但是使用原生的Hibernate Criteria

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

希望有所帮助。

我有同样的问题,我通过反转OR侧解决了它,例如:

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

没有工作,但像这样扭转OR方面:

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

工作得很好。 我不明白为什么,但它的确有效。 它可能与“短路”有关,但是在null的情况下,无论如何都要评估两个语句。 希望有人可以解释一下。