java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0) through jdbcTemplate

时间:2019-01-18 18:34:04

标签: arrays spring maven jdbctemplate

While updating data in database through spring jdbcTemplate, Please advise is there is any way so that I need not to hardcode the parameter Index,I am getting below error:

java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
    at com.mysql.cj.jdbc.ClientPreparedStatement.checkBounds(ClientPreparedStatement.java:1408)
    at com.mysql.cj.jdbc.ClientPreparedStatement.getCoreParameterIndex(ClientPreparedStatement.java:1421)
    at com.mysql.cj.jdbc.ClientPreparedStatement.setNull(ClientPreparedStatement.java:1686)
    at org.springframework.jdbc.core.StatementCreatorUtils.setNull(StatementCreatorUtils.java:308)
    at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:232)
    at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:166)
    at org.springframework.jdbc.core.ArgumentPreparedStatementSetter.doSetValue(ArgumentPreparedStatementSetter.java:66)
    at org.springframework.jdbc.core.ArgumentPreparedStatementSetter.setValues(ArgumentPreparedStatementSetter.java:47)
    at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:875)
    at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:870)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:633)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:870)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:931)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:941)
    at com.ganeshTrading.riceAppService.dao.impl.JdbcPurchaseDAO.updateStock(JdbcPurchaseDAO.java:151)
    at com.ganeshTrading.riceAppService.controller.PurchaseController.updateStock(PurchaseController.java:60)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)

Here, is my code:

public void updateStock(Stock stock) {
        String sql = "update stock_details set ";
        Object[] obj = new Object[3];
        if(stock.getRemainingStock() != null) {
            sql+= "remaining_stock = ? ";
            obj[0] = stock.getRemainingStock();
            if(stock.getCommodityPricePerKg() != null) {
                sql+= ", commodityPricePerKg = ? ";
                obj[1] = stock.getCommodityPricePerKg();
                sql += " where commodity_id = ? ";
                obj[2] = stock.getCommodityId();
            }
            else {
                sql += " where commodity_id = ? ";
                obj[1] = stock.getCommodityId();
            }
        }
        else if(stock.getCommodityPricePerKg() != null) {
            sql+= " commodityPricePerKg = ? ";
            obj[0] = stock.getCommodityPricePerKg();
            sql += " where commodity_id = ? ";
            obj[1] = stock.getCommodityId();
        }
        if(jdbcTemplate == null)
            jdbcTemplate = new JdbcTemplate(dataSource);
        System.out.println(obj.length);
        jdbcTemplate.update(sql, obj);

    }

Please advise what is wrong in my code or there is some other way to do this through jdbcTemplate. Thanks in advance.

2 个答案:

答案 0 :(得分:2)

问题在于SQL语句中的参数数量与提供的参数数量不匹配。通过查看代码并不明显,但是

Object[] obj = new Object[3];
obj[0] = "Duke";
jdbcTemplate.update(sql, obj);

基本相同
jdbcTemplate.update(sql, new Object[] { "Duke", null, null });

JdbcTemplate假定SQL语句和提供的参数数组中的参数数量相同。

要处理不同数量的参数,可以从数组更改为列表

List<Object> args = new ArrayList<>();
// some logic with args.add(...)
jdbcTemplate.update(sql, args.toArray());

替代方法是NamedParameterJdbcTemplate:

Map<String, Object> args = new HashMap<>();
args.put("name", "Duke");

NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
jdbcTemplate.update("UPDATE user SET name = :name", args);

答案 1 :(得分:0)

在:

    <plugin>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-maven-plugin</artifactId>
        <version>9.4.14.v20181114</version>
    </plugin>

并且:

sql+= " commodityPricePerKg = ? "

您确定db中的字段是这样命名的吗?也许它被命名为“ commodity_price_per_kg”?