2011-08-08 40 views
4

我在oracle中有一個自定義函數,在刪除記錄後返回一個數字。我可以在sql_plus得到一個值,如如何調用自定義Oracle函數返回JPA的值

call my_function(4) into :out_number; 

其中out_number是被定義爲數字的變量。

我可以驗證out_number在我做「PRINT OUT_NUMBER」時有一個值。

我的問題是如何從JPA調用這個函數。

我已經試過像

Query query = em.createNativeQuery("{call my_function(?)}"); 
query.serParameter(1, 4); 
return query.executeUpdate(); 

,並得到基本創建my_function沒有定義的錯誤。我如何獲得SQL_PLUS中CALL ... INTO的返回值?

如果這種方法不可取,有人可以推薦任何建議嗎? JPA是目前唯一的選擇。我可以創建一個存儲過程,但我不確定是否可以從中獲取返回值,因爲OUT參數不受支持。

感謝您的幫助提前!

+0

Tulskiy,我不能使用'select ... from dual',因爲my_function執行刪除語句(DML)。我試圖使用BEGIN my_function(?);結束;但是,我沒有運氣來獲得回報價值。 –

回答

2

我用這個在Oracle執行本機功能:

Query query = em.createNativeQuery("select my_function(:param) from dual"); 
query.setParameter("param", 4); 
return query.getSingleResult(); 
0

如果您正在使用的EclipseLink您可以使用StoredFunctionCall對象調用存儲功能,如這一點。

您也可以使用@NamedStoredFunctionQuery將其定義爲命名查詢。

1

這是一個很老的問題,但我還沒有在這裏找到合適的解決方案 ...這裏是我的項目工作的代碼:

EntityManager em; 
    String functionName = "NameOfStoredFunction"; 
    Map<String, Object> arguments = new LinkedHashMap(); 
    arguments.put("nameOfArgument", "value"); 
    StoredFunctionCall functionCall = new StoredFunctionCall(); 
    functionCall.setProcedureName(functionName); 
    functionCall.setResult("RESULT", String.class); 

    for(String key : arguments.keySet()){ 
     functionCall.addNamedArgumentValue(key, arguments.get(key)); 
    } 

    ValueReadQuery valQuery = new ValueReadQuery(); 
    valQuery.setCall(functionCall); 

    Query query = ((JpaEntityManager)em.getDelegate()).createQuery(valQuery); 

    String call_result = (String)query.getSingleResult(); 
+0

上面的代碼適用於修改數據庫中數據的函數(使用DML語句)。 –

+0

我想這隻與EclipseLink相關。 – Vadzim

0

https://vladmihalcea.com/how-to-call-oracle-stored-procedures-and-functions-from-hibernate/

首先,我們可以只需調用Oracle函數就像任何其他的SQL查詢:

BigDecimal commentCount = (BigDecimal) entityManager 
    .createNativeQuery(
     "SELECT fn_count_comments(:postId) FROM DUAL" 
    ) 
    .setParameter("postId", 1L) 
    .getSingleResult(); 

另一種方法是使用普通JDBC API調用數據庫函數:

Session session = entityManager.unwrap(Session.class); 

final AtomicReference<Integer> commentCount = 
    new AtomicReference<>(); 

session.doWork(connection -> { 
    try (CallableStatement function = connection 
      .prepareCall(
       "{ ? = call fn_count_comments(?) }" 
      ) 
     ) { 
     function.registerOutParameter(1, Types.INTEGER); 
     function.setInt(2, 1); 
     function.execute(); 
     commentCount.set(function.getInt(1)); 
    } 
}); 
相關問題