2011-08-08 25 views
4

レコードを削除した後にoracleでカスタム関数が返されました。JPAから値を返すカスタムOracle関数を呼び出す方法

call my_function(4) into :out_number; 

などのsql_plusで値を取得できました。ここで、out_numberは数値として定義された変数です。

"OUT_NUMBERを印刷する"ときに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、my_functionがdeleteステートメント(DML)を実行するため、Tulskiyは 'select ... from dual'を使用できません。私は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/から:

まず、我々はできます

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

もう1つの方法は、プレーン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)); 
    } 
}); 
関連する問題