java - 当我有 PIVOT 时,使用 JPA 如何在 native 查询中设置参数

标签 java oracle hibernate jpa oracle11g

   q = createQuery( "  select * from ( ( SELECT * FROM ( SELECT dt.route_id , dt.amount , dc.card_type_id FROM DDRC_TRANS\n" +
                "dt , DDRC_CARD dc WHERE ( dt.card_id = dc.id AND dt.insert_time >= ('02-JAN-2000 04:00:00 AM')\n" + 
                "AND dt.insert_time <= ('02-FEB-2050 04:00:00 AM') AND dt.route_id IN ( '1', '3' ) ) ) PIVOT\n" + 
                "( SUM(amount ) FOR card_type_id IN ( 1,2,3 ) ) ) )"
                , clazz);

好的,一切看起来都不错!我可以运行这个查询,它也会返回结果!

但是我发现了一个问题。如果我需要设置参数怎么办?例如像这样

 q = createQuery( "  select * from ( ( SELECT * FROM ( SELECT dt.route_id , dt.amount , dc.card_type_id FROM DDRC_TRANS\n" +
                "dt , DDRC_CARD dc WHERE ( dt.card_id = dc.id AND dt.insert_time >= ('02-JAN-2000 04:00:00 AM')\n" + 
                "AND dt.insert_time <= ('02-FEB-2050 04:00:00 AM') AND dt.route_id IN ( '1', '3' ) ) ) PIVOT\n" + 
                "( SUM(amount ) FOR card_type_id IN ( :param ) ) ) )"
                , clazz);


         List<String> valueList = Arrays.asList("1,2,3");
         q.setParameter("param", valueList);

现在我遇到了这种类型的错误:

java.sql.SQLException: ORA-56900: bind variable is not supported inside pivot|unpivot operation
为什么?我怎样才能解决这个问题?这是 hibernate BUG吗?

最佳答案

问题看起来像 ojdbc 不允许在 PIVOT 子句中绑定(bind)变量,因为 it is not supported .

您发布的第一个查询以显式方式设置值。在第二个中,您间接使用 preparedStatement通过 JPA 提供商。 这就是为什么您最终得到如下所示的不受支持的查询语句(请注意 IN 子句的参数化值)

select * .... PIVOT ( SUM(amount ) FOR card_type_id IN ( ? ) ) ) ) 

尽管它无论如何都不起作用,但您必须意识到您没有设置值列表。在上面的查询中,您只需设置一个参数。

对于您的 native 查询(假设您在 createQuery 方法中使用 EntityManager.createNativeQuery 创建),

q = createQuery( "select * .... card_type_id IN ( :param ) ");
List<String> valueList = Arrays.asList("1,2,3");
q.setParameter("param", valueList);

您最终生成的内容取决于 JPA 提供程序如何用 valueList 替换 :param,但它只是一个参数替换而不是列表。例如,Hibernate会生成preparedStatement像这样

select * .... card_type_id IN ( ? )

在设置了 valueList 参数后最终采用下一种形式,

select * .... card_type_id IN ( [1,2,3] )

你真正应该实现的是一个像这样的preparedStatement(注意许多参数)

select * .... card_type_id IN ( ?,?,? )

为此,valueList 应如下所示:

List<String> valueList = Arrays.asList("1","2","3");

然后语句将采用上面准备的,最后:

select * .... card_type_id IN ( '1','2','3' )

关于java - 当我有 PIVOT 时,使用 JPA 如何在 native 查询中设置参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31859472/

相关文章:

java - 从 XJC 输出中省略 @XmlSeeAlso

oracle - 我可以在 PL/SQL 中获得多行错误消息吗?

java - Hibernate 复合元素映射

java - Maven - 在子项目/父项目和子项目之间共享类

java - java中如何查找数组的子数组

java - 没有编码器发现嵌套 Java 类的错误

sql - 这是子查询还是只是内部联接

linux - 配置 Oracle 监听器以在外部监听

java - hibernate 升级后代码覆盖率显着下降 - 未涵盖 getter 和 setter - 有什么想法吗?

java - 自定义列表的麻烦