2016-05-17 62 views
0

我有SP只有4個輸出PARAMS和無輸入參數,可以和我StoredProcedureItemReader的conf這個樣子的Spring Batch的StoredProcedureItemReader只輸出參數讀取StoredProc(無輸入PARAMS)

<bean id="spItemReader"> 
    class="org.springframework.batch.item.database.StoredProcedureItemReader" > 
    <property name="dataSource" ref="dataSource"/> 
    <property name="procedureName" value="mynamespace.spname"/> 
    <property name="refCursorPosition" value="1"></property> 
    <property name="rowMapper"> 
     <bean class="MyRowMapper"/> 
    </property> 
    <property name="parameters"> 
     <list> 
      <bean class="org.springframework.jdbc.core.SqlParameter"> 
       <constructor-arg index="0" value="column1"/> 
       <constructor-arg index="1"> 
        <util:constant static-field="java.sql.Types.SMALLINT"/> 
       </constructor-arg> 
      </bean> 
      <bean class="org.springframework.jdbc.core.SqlParameter"> 
       <constructor-arg index="0" value="P_column2"/> 
       <constructor-arg index="1"> 
        <util:constant static-field="java.sql.Types.VARCHAR"/> 
       </constructor-arg> 
      </bean> 
      <bean class="org.springframework.jdbc.core.SqlParameter"> 
       <constructor-arg index="0" value="P_column3"/> 
       <constructor-arg index="1"> 
        <util:constant static-field="java.sql.Types.INTEGER"/> 
       </constructor-arg> 
      </bean> 
      <bean class="org.springframework.jdbc.core.SqlParameter"> 
       <constructor-arg index="0" value="P_column4"/> 
       <constructor-arg index="1"> 
        <util:constant static-field="java.sql.Types.CHAR"/> 
       </constructor-arg> 
      </bean> 
     </list> 
    </property> 
</bean> 

我有數據源作爲org.springframework.jdbc.datasource.DriverManagerDataSource的實例和連接DB2com.ibm.db2.jcc.DB2Driver作爲驅動程序類。

而我的工作配置如下:

<job id="testJob" xmlns="http://www.springframework.org/schema/batch"> 
    <step id="step1"> 
     <tasklet> 
      <chunk reader="spItemReader" writer="eventItemWriter" 
       commit-interval="1" /> 
     </tasklet> 
    </step> 
</job> 

<bean id="jobRepository" 
    class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"> 
    <property name="transactionManager" ref="transactionManager" /> 
</bean> 

<bean id="transactionManager" 
    class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" /> 

<bean id="jobLauncher" 
    class="org.springframework.batch.core.launch.support.SimpleJobLauncher"> 
    <property name="jobRepository" ref="jobRepository" /> 
</bean> 

我有作家爲StaxEventItemWriter和適當unmarshaller配置。

問題是,當我運行的批處理,我不斷收到:

Caused by: org.springframework.jdbc.BadSqlGrammarException: Executing stored procedure; bad SQL grammar [{call mynamespace.spname(?, ?, ?, ?)}]; nested exception is com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-440, SQLSTATE=42884, SQLERRMC=PROCEDURE;BSCPROC.PKA109, DRIVER=4.19.26

我不知道我錯過了什麼,請指教我應該怎麼解決這個問題。 讓我也知道是否需要更多信息。

回答

2

最後,我自己找到了一個解決方案。 Spring批量API提供StoredProcedureItemReader提供PreparedStatementSetter,它必須被註釋爲CallableStatement。由於StoredProcedures不適用於PreparedStatements。我們將不得不通過爲PreparedStatementSetter提供自定義實現來覆蓋setValues方法。這裏是配置應該看起來如何。

注:屬性名= 「preparedStatementSetter」 REF = 「paramSet」

代碼:

<bean id="spItemReader" 
class="org.springframework.batch.item.database.StoredProcedureItemReader" > 
<property name="dataSource" ref="dataSource"/> 
<property name="procedureName" value="mynamespace.spname"/> 
<property name="refCursorPosition" value="1"></property> 
<property name="preparedStatementSetter" ref="paramSet" ></property> 
<property name="rowMapper"> 
    <bean class="MyRowMapper"/> 
</property> 
<property name="parameters"> 
    <list> 
     <bean class="org.springframework.jdbc.core.SqlParameter"> 
      <constructor-arg index="0" value="column1"/> 
      <constructor-arg index="1"> 
       <util:constant static-field="java.sql.Types.SMALLINT"/> 
      </constructor-arg> 
     </bean> 
     <bean class="org.springframework.jdbc.core.SqlParameter"> 
      <constructor-arg index="0" value="P_column2"/> 
      <constructor-arg index="1"> 
       <util:constant static-field="java.sql.Types.VARCHAR"/> 
      </constructor-arg> 
     </bean> 
     <bean class="org.springframework.jdbc.core.SqlParameter"> 
      <constructor-arg index="0" value="P_column3"/> 
      <constructor-arg index="1"> 
       <util:constant static-field="java.sql.Types.INTEGER"/> 
      </constructor-arg> 
     </bean> 
     <bean class="org.springframework.jdbc.core.SqlParameter"> 
      <constructor-arg index="0" value="P_column4"/> 
      <constructor-arg index="1"> 
       <util:constant static-field="java.sql.Types.CHAR"/> 
      </constructor-arg> 
     </bean> 
    </list> 
</property> 
</bean> 

<bean id="paramSet" class="com.jpmc.ib.asup.batch.CustomSPParamSetter" ></bean> 

PreparedStatementSetter實現:

代碼:

public class CustomSPParamSetter implements PreparedStatementSetter{ 

@Override 
public void setValues(PreparedStatement ps) throws SQLException { 

    CallableStatement eventCallableSt=(CallableStatement)ps; 
    eventCallableSt.registerOutParameter(1, java.sql.Types.SMALLINT); 
    eventCallableSt.registerOutParameter(2, java.sql.Types.VARCHAR); 
    eventCallableSt.registerOutParameter(3, java.sql.Types.INTEGER); 
    eventCallableSt.registerOutParameter(4, java.sql.Types.CHAR); 
} 
} 

它不合乎邏輯的在Spring配置文件和PreparedStatementSetter中聲明SP參數。但這對我來說是正確的工作解決方案。

+0

我可以問一下在RowMapper中如何獲取out參數的值?我注意到你已經使用 Shilan

+0

請共享完整的代碼,如果有..如何通過使用此存儲過程中傳遞當前日期作爲參數.. – DEADEND