我在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参数。
提前感谢您的帮助!
答案 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));
}
}