【问题标题】:How to resolve java.sql.SQLException: Parameter index out of range?如何解决 java.sql.SQLException:参数索引超出范围?
【发布时间】:2018-07-04 18:53:09
【问题描述】:

我是新手开发人员。在我的代码中,html 页面在浏览器中正确显示,但在提交数据后它没有调用 post 方法,因此没有将数据存储在我的 mysql workbence 数据库中。数据库中的模式名称是注册,表名称是 reg_details。我使用的是 apache tomcat 服务器。

HTML 文件:

<!DOCTYPE html>
    <html>
    <head>
    <meta charset="ISO-8859-1">
    <title>Insert title here</title>
    </head>
    <body>
    <form action="Registration" method="post" autocomplete="on">
    <fieldset>
    <legend>Registration Details:</legend>
    First Name &nbsp <input type="text" name="firstname" autofocus> &nbsp Middle name &nbsp <input type="text" name="middlename"> &nbsp Last Name &nbsp <input type="text" name="lastname"><br><br>
    Address &nbsp <br> <textarea name="address" rows="2" cols="25"></textarea>
    <br><br>
    Gender &nbsp <input type="radio" name="gender" value="male"> Male <input type="radio" name="gender" value="female"> Female<br><br>
    Mobile No. &nbsp <input type="text" name="mobileno"> <br><br>
    Email Id &nbsp <input type="email" name="emailid"> <br><br> 
    Birth Date &nbsp <input type="date" name="birthday"><br><br>
    Username &nbsp <input type="text" name="username"><br><br>
    Password &nbsp <input type="password" name="password"><br><br>
    <input type="submit" value="Submit">
    </fieldset>
    </form>
    </body>
    </html>

registration.java 文件

    import java.io.IOException;
        import java.io.PrintWriter;
        import java.sql.*;
        import javax.servlet.ServletException;
        import javax.servlet.annotation.WebServlet;
        import javax.servlet.http.HttpServlet;
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;

        /**
         * Servlet implementation class Registration
         */
        @WebServlet("/Registration")
        public class Registration extends HttpServlet {

            private static final long serialVersionUID = 1L;
            /**
             * @see HttpServlet#HttpServlet()
             */
            public Registration() {
                super();
                // TODO Auto-generated constructor stub
            }

            /**
             * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
             */
            public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                // TODO Auto-generated method stub

                //http://localhost:12093
                try {
                    String firstname=request.getParameter("firstname");
                    PrintWriter print = response.getWriter();
                    print.println(firstname);
                    Class.forName("com.mysql.jdbc.Driver");
                    java.sql.Connection connection;

                    connection =  DriverManager.getConnection("jdbc:mysql://localhost:3306/registration","root","rohan");
                    PreparedStatement ps=connection.prepareStatement("INSERT INTO reg_details (name) values ('rk');");
                    //Statement stmt = connection.createStatement();
                //  ResultSet result = stmt.executeQuery("INSERT INTO reg_details (name) values ('rohan');");
                    ps.setString(1, firstname);
                    ps.executeUpdate();
        //          while(result.next())
        //          {
        //              PrintWriter print = response.getWriter();
        //              print.println(result.getString("name"));
        //          }
connection.close();
            ps.close();
                } catch (SQLException | ClassNotFoundException e) {
                    // TODO Auto-generated catch block
                e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

For writing connection con = DriverManager.getconnection(); its telling me to write like this java.sql.Connection connection; or connection con = (connection)DriverManager.getconnection();  

我更新了你的建议。我最后关闭了连接并删除了服务方法,但在执行相同的错误退出后。我正在附加我的控制台,以便它对您有所帮助。我使用 mysql-connector-java-5.1.44-bin.jar 进行数据库连接。

这是来自服务器控制台的堆栈跟踪:

org.apache.tomcat.util.digester.SetPropertiesRule begin
WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:Hospital Queue Management' did not find a matching property. org.apache.catalina.startup.VersionLoggerListener log
INFO: Server built:          
org.apache.catalina.startup.VersionLoggerListener log
INFO: Server number:         8.0.48.0
org.apache.catalina.startup.VersionLoggerListener log
INFO: Architecture:          amd64
INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
 org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-nio-8085"]
 org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-nio-8019"]
 org.apache.catalina.startup.Catalina start
INFO: Server startup in 1512 ms
 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.

java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:964)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:897)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:886)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:860)
    at com.mysql.jdbc.PreparedStatement.checkBounds(PreparedStatement.java:3327)
    at com.mysql.jdbc.PreparedStatement.setInternal(PreparedStatement.java:3312)
    at com.mysql.jdbc.PreparedStatement.setString(PreparedStatement.java:4027)
    at Registration.doPost(Registration.java:44)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
    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)

【问题讨论】:

  • 别忘了关闭你的连接
  • 欢迎来到 Stack Overflow!您能否详细说明您的代码如何“不起作用”?你期待什么,实际发生了什么?如果您遇到异常/错误,请发布它发生的行和异常/错误详细信息。请edit这些详细信息,否则我们可能无法提供帮助。
  • 既然你有这个:e.printStackTrace() 请检查你正在使用的服务器的日志(tomcat、jetty、w/e)来运行应用程序,看看那里是否打印了异常。这是发现问题并解决问题的重要信息。此外,注意基本概念。 MySQL 是数据库引擎,MySQL Workbench 是一个客户端工具,可让您“查看” MySQL 引擎中数据库和表的人工表示。
  • 我不喜欢你的“服务”方法的外观——如果你删除它会发生什么。我认为这有效地拦截了您对 servlet 的所有调用
  • @DaiveH 感谢回复我删除了服务方法,但代码仍然没有将数据存储在 mysql 数据库中。

标签: java mysql sql servlets prepared-statement


【解决方案1】:

java.sql.SQLException: 参数索引超出范围 (1 > number of 参数,为0)。

preparedstatement 没有占位符(参数个数为0

INSERT INTO reg_details (name) values ('rk')

但是,您正在尝试设置

ps.setString(1, firstname);

这就是原因,你得到了例外。您需要更改 SQL 以接受一个参数

INSERT INTO reg_details (name) values (?)

【讨论】:

    【解决方案2】:

    如果您在调用存储过程时遇到此异常:

    java.sql.SQLException: 参数索引 X 超出范围 (1, Z)

    如果你正在使用

    1. 弹簧数据 jpa
    2. 返回一个值。例如- id 字段

    那么你必须注意这些事情。

    @Repository
    public interface UserDao extends JpaRepository<User, Long>{
    
        @Procedure(procedureName = "PersistUserInfo" , outputParameterName = "id")
        long saveUserInfo(String userName, String firstName, String lastName);
    
    }
    
    1. 需要在属性名outputParameterName = "id"
    2. 中以@Proceddure语法定义OUT参数
    3. OUT 参数是存储过程中的最后一个参数。 (这很重要)。

    所以你的存储过程应该是这样的:

    CREATE PROCEDURE `PersistUserInfo`(IN userName varchar(20), IN firstName varchar(100), IN lastName varchar(100), OUT id BIGINT)
    

    在休眠日志中你会发现 SP 的调用是这样的:

    {call PersistUserInfo(?,?,?,?)}
    

    通过这些更改,我能够解决问题并能够调用存储过程。

    【讨论】:

    • 查看堆栈跟踪。这显然是一个名为Registration 的普通HttpServlet 子类,它覆盖了doPost() 方法,该方法直接JDBC 调用PreparedStatementsetString()。没有 Spring 框架,没有 JPA,所以回答没用。
    猜你喜欢
    • 1970-01-01
    • 2020-03-17
    • 2020-06-20
    • 1970-01-01
    • 2014-07-11
    • 2013-04-18
    • 2014-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多