调用从 Hibernate 返回记录列表的 PL/SQL 函数

Posted

技术标签:

【中文标题】调用从 Hibernate 返回记录列表的 PL/SQL 函数【英文标题】:Call PL/SQL function that returns list of records from Hibernate 【发布时间】:2021-03-04 06:53:08 【问题描述】:

在尝试调用此类 PL/SQL 函数时

type t_messages_rec is record (
   id NUMBER
  ,code VARCHAR2(30)
  ,type VARCHAR2(3)
  ,text VARCHAR2(100)
);
  
type t_messages_tab is table of t_messages_rec;
  
function get_and_clear_messages return t_messages_tab
pipelined;

来自java

import javax.persistence.EntityManager;
import oracle.jdbc.OracleTypes;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.jdbc.ReturningWork;

// imports are listed for clarity 
    
    ReturningWork work = connection -> 
      try (CallableStatement function = connection.prepareCall(" ? = call PACKAGE_NAME.get_and_clear_messages() ")) 
        function.registerOutParameter(1, OracleTypes.REF_CURSOR);
        function.execute();

        return function.getResultSet();
      
    ;

    Session session = entityManager.unwrap(Session.class);
    try 
      return (List<Message>) session.doReturningWork(work);
     catch (HibernateException e) 
      e.printStackTrace();
    

不幸的是它导致异常:(

Caused by: Error : 6550, Sql = BEGIN :1 := PACKAGE_NAME.get_and_clear_messages() ; END;,
OriginalSql =  ? = call PACKAGE_NAME.get_and_clear_messages() , 
Error Msg = ORA-06550: line 61, column 12:
PLS-00653: aggregate/table functions are not allowed

我怀疑,(但我可能是错的),这条线

  try (CallableStatement function = connection.prepareCall(" ? = call PACKAGE_NAME.get_and_clear_messages() ")) 

表示我想将调用结果存储在“?”中变量,流水线函数所不允许的。

使用 Hibernate 从流水线函数获取结果的正确方法是什么?

【问题讨论】:

【参考方案1】:

我整理好了。显然流水线函数可以用标准 sql 查询 :)

例如:

SELECT * FROM PACKAGE_NAME.GET_AND_CLEAR_MESSAGES() m

【讨论】:

以上是关于调用从 Hibernate 返回记录列表的 PL/SQL 函数的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL API调用/查询返回多条记录,如何传入多个变量

忽略 PL/SQL 函数的返回值

PL/pgSQL - 从 FUNCTION 返回单个记录

在远程过程调用中返回记录列表

如何从 Oracle PL/SQL 函数中返回现有表中的记录?

是否可以从 jdbc 调用 pl/sql 函数并按名称注册返回值?