2016-05-17 8 views
0

Ich habe SP mit nur 4 Ausgang params und keine Eingabe params und meine StoredProcedureItemReader conf aussehen wie diesesSpring Batch StoredProcedureItemReader StoredProc mit nur Ausgabeparameter (keine Eingabe 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> 

ich die Datenquelle haben zu lesen, wie Instanz von org.springframework.jdbc.datasource.DriverManagerDataSource und Verbinden mit DB2 mit com.ibm.db2.jcc.DB2Driver als Treiberklasse.

Und mein Job-Konfiguration ist wie folgt:

<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> 

Ich habe Schriftsteller wie StaxEventItemWriter und richtige unmarshaller Konfiguration.

Das Problem ist, wenn ich die Batch laufen, ich erhalte:

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

Ich bin nicht sicher, was ich bin fehlt, bitte Rat, wie ich dieses Problem beheben sollte. Lassen Sie mich auch wissen, ob weitere Informationen benötigt werden.

Antwort

2

Endlich habe ich selbst eine Lösung gefunden. Die Spring Batch-API wird bereitgestellt StoredProcedureItemReader bietet PreparedStatementSetter, die zu CallableStatement typecast sein muss. Weil StoredProcedures nicht mit PreparedStatements funktionieren wird. Wir müssen die setValues-Methoden überschreiben, indem wir eine benutzerdefinierte Implementierung für PreparedStatementSetter bereitstellen. Und so sollte die Konfiguration aussehen.

Hinweis: property name = "preparedStatementSetter" ref = "ParamSet"

Code:

<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 Umsetzung:

Code:

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); 
} 
} 

Sein nicht logisch zu Deklarieren Sie die SP-Parameter in der Spring-Konfigurationsdatei und im PreparedStatementSetter. Aber das ist die richtige Arbeitslösung für mich.

+0

Kann ich fragen, wie erhalten Sie Werte von out Parameter in RowMapper? Ich habe bemerkt, dass Sie verwendet haben Shilan

+0

Bitte teilen Sie den vollen Code wenn .. Wie das aktuelle Datum als Parameter in der gespeicherten Prozedur mit diesem übergeben. – DEADEND

Verwandte Themen