Java 使用spring存储过程调用oracle存储过程
我一直试图得到一段使用spring和oracle存储过程并带有参数的代码,但发现很难运行。指定的存储过程预期使用三个参数,但在错误中似乎需要四个参数。第四个参数是要返回的游标 以下是我的Oracle(9i)软件包规范:Java 使用spring存储过程调用oracle存储过程,java,spring,stored-procedures,oracle9i,java-ee-5,Java,Spring,Stored Procedures,Oracle9i,Java Ee 5,我一直试图得到一段使用spring和oracle存储过程并带有参数的代码,但发现很难运行。指定的存储过程预期使用三个参数,但在错误中似乎需要四个参数。第四个参数是要返回的游标 以下是我的Oracle(9i)软件包规范: CREATE OR REPLACE PACKAGE pkg_data_load AS procedure sp_atm_withdrawal(p_catermid IN VARCHAR2, p_start_date IN VARCHAR2,p_end_date IN VARCH
CREATE OR REPLACE PACKAGE pkg_data_load AS
procedure sp_atm_withdrawal(p_catermid IN VARCHAR2,
p_start_date IN VARCHAR2,p_end_date IN VARCHAR2,p_out out sys_refcursor);
END;
包体如下:
CREATE OR REPLACE PACKAGE BODY pkg_data_load
AS
procedure sp_atm_withdrawal
(
p_catermid IN VARCHAR2,
p_start_date IN VARCHAR2,
p_end_date IN VARCHAR2,
p_out out sys_refcursor
) as
v_start_date date := to_date(p_start_date,'yyyy/mm/dd');
v_end_date date := to_date(p_end_date,'yyyy/mm/dd');
begin
open p_out for select
b.nam_branch BRANCH_NAME
, a.bcode brn_Code
, a.acct_no Acct_no
from table a, table b where b.cod_Cc_brn= a.cod_org_brn
and a.cod_reply=0
and b.flg_mnt_status='A'
and a.cod_proc not in ( 312000, 382000, 311000, 381000)
and a.cod_txn_literal<>'SCD'
and a.ca_term_id in (
select ca_term_id from tablec where flg_mnt_status='A')
and a.dat_post_stl between v_start_date and v_end_date
and a.ca_term_id = p_catermid;
end sp_atm_withdrawal;
END pkg_data_load;
下面是我的DAO实现方法
public List<Atm> loadWithdrawal(String branch, String startDate, String endDate) {
if (this.jdbcTemplate == null) {
System.out.print("JDBC TEMPLATE IS NULL");
}
List<Atm> withdrawals = null;
try
{
AtmStoredProcedures st = new AtmStoredProcedures(jdbcTemplate,"pkg_data_load.sp_atm_withdrawal");
Map results = st.getCashWithdrawals(branch, startDate, endDate);
withdrawals = (List<Atm>) results.get("sys_refcursor");
} catch (DataAccessException ex) {
System.out.print(ex.getMessage());
}
return withdrawals;
}
对declareParameter()的调用顺序必须与Oracle存储过程的顺序相同。试试这个:
declareParameter(new SqlParameter("branch", Types.VARCHAR));
declareParameter(new SqlParameter("startDate", Types.VARCHAR));
declareParameter(new SqlParameter("endDate", Types.VARCHAR));
declareParameter(new SqlOutParameter("sys_refcursor",OracleTypes.CURSOR, rowMapper));
为数据源配置创建bean:
classpath:datasource.properties
创建一个dao,并将数据源(applicationContext.xml)注入到该dao中:
然后创建一个用于将Oracle数组转换为java列表的类
公共类OracleList实现SqlReturnType{
公共对象getTypeValue(CallableStatement cs、int paramIndex、int sqlType、String typeName)抛出SQLException{
对象[]结构=(对象[])((数组)cs.getObject(paramIndex)).getArray();
List po_List=new ArrayList();
对于(inti=0;我认为这帮了大忙。
CallableStatementCallback; bad SQL grammar
[{call pkg_data_load.sp_atm_withdrawal(?, ?, ?, ?)}];
nested exception is java.sql.SQLException:
ORA-06550: line 1, column 7: PLS-00306: wrong number or
types of arguments in call to 'SP_ATM_WITHDRAWAL'ORA-06550:
line 1, column 7: PLS-00306: wrong number or types of arguments
in call to 'SP_ATM_WITHDRAWAL'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
declareParameter(new SqlParameter("branch", Types.VARCHAR));
declareParameter(new SqlParameter("startDate", Types.VARCHAR));
declareParameter(new SqlParameter("endDate", Types.VARCHAR));
declareParameter(new SqlOutParameter("sys_refcursor",OracleTypes.CURSOR, rowMapper));
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations"><list>
<value>classpath:datasource.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="true" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
<bean id="defaultDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="accessToUnderlyingConnectionAllowed" value="true"/>
</bean>
<bean id="testDao" class="com.test.dao.testDao">
<property name="dataSource" ref="dataSource" />
</bean>
public class OracleLists implements SqlReturnType {
public Object getTypeValue(CallableStatement cs, int paramIndex,int sqlType, String typeName) throws SQLException {
Object[] structs = (Object[]) ((ARRAY)cs.getObject(paramIndex)).getArray();
List<String> po_list = new ArrayList<String>();
for(int i=0;i<structs.length ;i++){
po_list.add(String.valueOf(structs[i]));
}
return po_list;
}
}
public class TestDao {
private SimpleJdbcCall simpleJdbcCall;
public void setSimpleJdbcCall(SimpleJdbcCall simpleJdbcCall;) {
this.simpleJdbcCall = simpleJdbcCall;
}
public List<String> getTestParameter(Object object) {
MapSqlParameterSource in = new MapSqlParameterSource();
in.addValue("IN_PARAM1", object.getInParam1);
in.addValue("OUT_PARAM1", null,OracleTypes.ARRAY, object.getOutParam1);
Map<String, Object> result = simpleJdbcCall.execute(in);
List<String> stringList = (List<String>) result.get("OUT_PARAM1");
return stringList ;
}
simpleJdbcCall= new SimpleJdbcCall(dataSource)
.withSchemaName("TESTSCHEMA")
.withCatalogName("TESTPACKAGE")
.withProcedureName("TESTPROC")
.declareParameters(
new SqlParameter("IN_PARAM",
OracleTypes.VARCHAR,
"IN_PARAM"),
new SqlInOutParameter(
"OUT_PARAM1",
OracleTypes.ARRAY,
TestOracleType,
new OracleLists()),
);
}