当使用sqlplus调用时,我有以下过程:
SQL> exec test_proc('test_search', :varcursor);
工作得很好,并给出了预期的结果(表中的id列表)。
CREATE OR REPLACE PROCEDURE test_proc
(search_term IN varchar2,
c1 OUT SYS_REFCURSOR)
AS
BEGIN
OPEN c1 for
select test.id
from test_table t
WHERE JSON_TEXTCONTAINS(t.test_col, '$', search_term);
DBMS_SQL.RETURN_RESULT(c1);
END test_proc;
然而,如果从我的Spring应用程序中使用JPA/eclipselink调用,结果总是null。
StoredProcedureQuery storedProcedure = em.createStoredProcedureQuery("test_proc")
.registerStoredProcedureParameter(1, String.class, ParameterMode.IN)
.registerStoredProcedureParameter(2, Class.class, ParameterMode.REF_CURSOR)
.setParameter(1, "test");
// execute SP
storedProcedure.execute(); --> true
List<Object[]> res = storedProcedure.getResultList();
直接在jdbc驱动程序上它也是空的。
Connection conn = DataSourceUtils.getConnection(dataSource);
CallableStatement st = null;
ResultSet rs = null;
try {
st = conn.prepareCall( "{call test_proc(?,?)}" );
st.setString(1, "test");
st.registerOutParameter( 2, OracleTypes.CURSOR );
boolean hadResults = st.execute();
System.out.println( hadResults ); --> always false
rs = (ResultSet) st.getObject(2);
while ( rs.next() )
{
System.out.println( rs.getInt(1) );
}
st.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
1条答案
按热度按时间zc0qhyus1#
这里似乎发生了一些奇怪的事情。
首先,您的存储过程很奇怪,因为它试图同时以
OUT
参数和隐式结果的形式返回来自游标的数据。(a)通过OUT
参数或(B)通过隐式结果,但不能同时通过这两种方式。(我的建议是通过OUT
参数返回它,方法是删除对DBMS_SQL.RETURN_RESULT
的调用。)但是,如果您没有更改存储过程的选项,那么您将不得不接受它返回的隐式结果。似乎通过隐式结果返回游标会覆盖通过
OUT
参数返回游标。第二件奇怪的事情是,OracleJDBC驱动程序似乎并不完全遵循隐式结果的JDBC标准。(Oracle在这里提供了示例代码),而JDBC标准规定使用
.getMoreResults()
返回后续结果,建议在调用.getMoreResults()
之前应该可以获得第一个结果。尝试调用
st.getMoreResults()
,检查它是否返回true
,然后通过调用st.getResultSet()
获取结果集。