IN 表达式中的 JPQL LOWER 函数

Posted

技术标签:

【中文标题】IN 表达式中的 JPQL LOWER 函数【英文标题】:JPQL LOWER Function in IN Expression [duplicate] 【发布时间】:2018-07-17 22:40:09 【问题描述】:

是否可以在 JPQL 中对 IN 表达式执行字符串函数,例如 LOWER

我正在尝试使用与此类似的 JPQL 查询(为简洁起见,查询已被简化):

SELECT e from MyEntity e WHERE LOWER(e.myAttribute) IN (LOWER(?1))

但是,对于 Hibernate/Oracle,这样的查询会导致类似于以下的错误:

WARN  o.h.e.jdbc.spi.SqlExceptionHelper - SQL Error: 7001, SQLState: 07001
ERROR o.h.e.jdbc.spi.SqlExceptionHelper - Invalid parameter count for "LOWER", expected count: "1"; SQL statement:
select e.my_attribute from my_entity e where lower(e.my_attribute) in (lower(?, ?, ?)) [7001-197]

生成的 SQL 查询无效:

lower(e.my_attribute) in (lower(?, ?, ?))

我认为应该更像下面这样:

lower(e.my_attribute) in (lower(?), lower(?), lower(?))

我不清楚 JPA 规范是否可以将字符串函数应用于 IN 表达式,如果不能,那么合理的替代方案是什么。我使用IN 表达式而不是OR,因为我的参数列表中有动态数量的项目,而我使用LOWER 是因为这些必须不区分大小写。

我正在使用 JPA 2.0/Hibernate 4.2/Oracle 11g/12c。不过,我宁愿避免使用任何特定于供应商的代码,并尽可能使用纯 JPA/JPQL。

【问题讨论】:

LOWER 采用单个字符串参数。参数1真的是String参数吗,如果是,为什么要使用IN?! @BillyFrost 参数 1 是字符串的列表。我需要将LOWER 字符串函数应用于每个列表项 我找到了***.com/questions/9178290/…,这似乎与我的问题重复,并且似乎表明不区分大小写的IN 是不可能的。 并且你不能使用一个列表,而不是将每个列表分离成一个单独的参数......所以它们可以在 LOWER 中使用(它接受一个参数)。而另一个问题并没有“似乎表明”这是不可能的,它明确表示这是不可能的,因为你想要 【参考方案1】:

JPQL 正在按设计运行。它的解释是正确的,这就是在你的代码中定义函数和参数的方式。

IN (LOWER(?1)) 子句声明将lower 函数应用于参数1,在您的情况下是list。因此您看到了错误。

要使用 Oracle 获得所需的结果,您可以使用内置的 Oracle 集合类型ODCIVARCHAR2LIST。所以 JPQL 将如下所示:

SELECT e 
FROM   myentity e 
WHERE  Lower(e.myattribute) IN 
       ( 
              SELECT Lower(column_value) 
              FROM   table(sys.odcivarchar2list(?1)))

注意:对于 Oracle 12.2+,您不需要 table 函数,所以下面也可以:

SELECT e 
FROM   myentity e 
WHERE  Lower(e.myattribute) IN 
       ( 
              SELECT Lower(column_value) 
              FROM   sys.odcivarchar2list(?1))

【讨论】:

谢谢,@amith-kumar,但我希望避免在我的 JPQL 中出现供应商特定的内容。 是的,它确实成为了依赖于数据库的查询,但如果你真的想通过查询来实现它,它是一个选项。我个人更愿意将已经小写的列表作为参数传递给不区分大小写的 IN 搜索。

以上是关于IN 表达式中的 JPQL LOWER 函数的主要内容,如果未能解决你的问题,请参考以下文章

JPQL:在构造函数表达式中接收集合

带有枚举值的 jpql IN 查询

使用构造函数表达式和 JPQL 的复合 DTO 投影

JPQL 构造函数表达式 - org.hibernate.hql.ast.QuerySyntaxException:表未映射

正确的表达式不是 JPQL/HQL 查询中的有效表达式

JPQL:CASE WHEN 中的布尔表达式何时需要与 TRUE/FALSE 进行显式比较?