我试图从Oracle存储过程中获取数据。问题是在我们的数据库中有一个函数和一个具有相同名称和相同参数的过程。
当我试着打电话时:
@Autowired
public void setDataSource (@Qualifier("dataSource") DataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.setResultsMapCaseInsensitive(true);
this.functionGetSomeCode = new SimpleJdbcCall(jdbcTemplate)
.declareParameters(new SqlOutParameter("RETURN", OracleTypes.NUMBER))
.withFunctionName("get_some_code").withSchemaName("XXX").withCatalogName("some_pkg");
}
public Integer getSomeCode (String incoming) {
SqlParameterSource incomingParameters = new MapSqlParameterSource().addValue("incoming", incoming);
return functionGetSomeCode.executeFunction(Integer.class, incomingParameters);
}
我得到一个例外:
springframework.dao.InvalidDataAccessApiUsageException: Unable to determine the correct call signature - multiple procedures/functions/signatures
有没有办法处理这种情况而不要求DBA将函数/过程重命名为不同的东西?
答案 0 :(得分:3)
我已经能够调用具有相同名称的功能和程序,但它并不总是有效。 在您的示例中,您似乎没有声明输入参数。尝试使用与包声明尽可能匹配的类型声明输入和输出参数。如果仍然无法正常工作,您可以尝试关闭ProcedureColumnMetaDataAccess,但一定要测试。
以下是一个例子:
protected SimpleJdbcCall buildJdbcCall(JdbcTemplate jdbcTemplate) {
SimpleJdbcCall call = new SimpleJdbcCall(jdbcTemplate)
.withSchemaName(schema)
.withCatalogName(catalog)
.withFunctionName(functionName)
// can use withProcedureName(procedureName) for procedures
//.withReturnValue()
// .withoutProcedureColumnMetaDataAccess() // may need this
.declareParameters(buildSqlParameters());
return call;
}
public SqlParameter[] buildSqlParameters() {
return new SqlParameter[]{
new SqlParameter("p_id", Types.VARCHAR),
new SqlParameter("p_office_id", Types.VARCHAR),
new SqlOutParameter("l_clob", Types.CLOB)
};
}
答案 1 :(得分:1)
如果您没有返回变量,则以下代码可以提供帮助。我遇到了我的代码在未声明out参数的情况下工作的同一问题,因为函数没有out参数。我通过将out参数声明为return解决了这个问题。代码如下。
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate.getDataSource()).withCatalogName("PACKAGE_NAME")
.withFunctionName("MY_FUNCTION_NAME").withoutProcedureColumnMetaDataAccess().declareParameters(
new SqlOutParameter("RETURN", Types.TIMESTAMP),
new SqlParameter("XYX_Y", Types.DATE),
new SqlParameter("HH_HDU", Types.VARCHAR)
);
jdbcCall.compile();
MapSqlParameterSource in = new MapSqlParameterSource();
in.addValue("XYX_Y", myDate);
in.addValue("HH_HDU", "PQR");
java.sql.Timestamp date = jdbcCall.executeFunction(java.sql.Timestamp.class, in);
答案 2 :(得分:0)
我也遇到了同样的问题。我有 2 个具有相同名称的处理器,但有一个不同的参数“lang_code_in”。看起来这个问题只是由于这个,它是因为 Spring/Spring 启动应用程序而出现的。所以我在“.withoutProcedureColumnMetaDataAccess().”之后添加了
final SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(dataSource).withCatalogName(catalogName)
.withProcedureName(procedureName)
.withoutProcedureColumnMetaDataAccess().
.declareParameters(buildPullOrderSqlParameters());
但在此之后它开始出现以下错误: org.springframework.jdbc.BadSqlGrammarException: CallableStatementCallback;错误的 SQL 语法 [{call NPIADM.CCM_JIGSAW_TEMPLATE_PKG.GET_UPC_XML_CONTENT(?, ?, ?)}];嵌套异常是 java.sql.SQLException: ORA-06550: line 1, column 7: PLS-00306:调用“GET_UPC_XML_CONTENT”时参数的数量或类型错误 ORA-06550:第 1 行,第 7 列: PL/SQL:忽略语句
然后我添加了所有输入和输出参数 declareParameters() 对象,如下所示,它开始正常工作。下面的代码有 P_ORDER_NUMBER_I 是输入参数,而 p_err_msg_o 是输出参数
public SqlParameter[] buildPullOrderSqlParameters() {
return new SqlParameter[]{
new SqlParameter("P_ORDER_NUMBER_I", Types.VARCHAR),
new SqlOutParameter("p_err_msg_o", Types.VARCHAR)
};
}