如何调用从JPA返回值的自定义Oracle函数

时间:2011-08-08 22:15:55

标签: java oracle jpa

我在oracle中有一个自定义函数,在删除记录后返回一个数字。我可以在sql_plus中获取一个值,例如

call my_function(4) into :out_number;

其中out_number是一个定义为数字的变量。

当我执行“PRINT OUT_NUMBER”时,我可以验证out_number是否有值。

我的问题是如何从JPA调用此函数。

我尝试过像

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

并且出现错误,基本上没有定义my_function。如何获取返回值,如CALL ... INTO在SQL_PLUS上?

如果不希望采用这种方法,有人可以推荐一下吗? JPA是目前我唯一的选择。我可以创建一个存储过程,但我不确定是否可以从中获取返回值,因为不支持OUT参数。

提前感谢您的帮助!

5 个答案:

答案 0 :(得分:2)

我用它在oracle中执行本机函数:

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

答案 1 :(得分: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();

答案 2 :(得分:1)

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

首先,我们可以像任何其他SQL查询一样简单地调用Oracle函数:

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 ) );
    }
} );

答案 3 :(得分:0)

如果您正在使用EclipseLink,则可以使用StoredFunctionCall对象来调用此类存储函数。

您还可以使用@NamedStoredFunctionQuery将其定义为命名查询。

答案 4 :(得分:0)

使用Spring Data JPA / Spring JDBC时,可以使用SimpleJdbcCall来调用函数和过程。

对于此类函数头:

FUNCTION get_text (p_param IN VARCHAR2) RETURN VARCHAR2

使用此呼叫:

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
import org.springframework.stereotype.Repository;

@Repository
public class MyRepository {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public String callGetTextFunction(String param) {
        SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
                .withCatalogName("PKG_PACKAGE") //package name
                .withFunctionName("GET_TEXT"); //function name
        SqlParameterSource paramMap = new MapSqlParameterSource()
                .addValue("p_param", param));
        //First parameter is function output parameter type.
        return jdbcCall.executeFunction(String.class, paramMap));
    }

}