How to call a custom Oracle function returning a value from JPA

后端 未结 5 487
暗喜
暗喜 2021-01-14 01:23

I have a custom function in oracle returning a number after deleting records. I could get a value in sql_plus such as

call my_function(4) into :out_number;
<         


        
相关标签:
5条回答
  • 2021-01-14 01:43

    It's a quite old question but I have not found here the proper solution... Here is a code that works in my project:

        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 讨论(0)
  • 2021-01-14 01:45

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

    First, we can simply call the Oracle function just like any other SQL query:

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

    Another approach is to call the database function using plain 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 ) );
        }
    } );
    
    0 讨论(0)
  • 2021-01-14 02:00

    If you are using EclipseLink you can use a StoredFunctionCall object to call a stored function such as this.

    You could also define it as a named query using the @NamedStoredFunctionQuery.

    0 讨论(0)
  • 2021-01-14 02:04

    I used this to execute native functions in oracle:

    Query query = em.createNativeQuery("select my_function(:param) from dual");
    query.setParameter("param", 4);
    return query.getSingleResult();
    
    0 讨论(0)
  • 2021-01-14 02:06

    When using Spring Data JPA / Spring JDBC you can use SimpleJdbcCall for calling functions and procedures.

    For such function header:

    FUNCTION get_text (p_param IN VARCHAR2) RETURN VARCHAR2
    

    Use this call:

    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));
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题