Java PreparedStatement无法执行MySQL Insert语句

时间:2012-12-03 03:52:58

标签: sql jdbc prepared-statement

我正在尝试在Java中使用PreparedStatement将新用户插入数据库。我创建了一个格式正确的SQL语句,但由于某种原因,在调用executeUpdate()时会产生错误;

DatabaseConnection dbconnection = DatabaseConnection.getInstance();
Connection con = dbconnection.getConnection();
PreparedStatement pstmt; // Prepare Statement automatically sanitizes inputs
    try {
        pstmt = con.prepareStatement("INSERT INTO " + TABLE_NAME + " (" + USERNAME + ", " + PASSWORD_HASH + ", " + EMAIL + ") VALUES (?, ?, ?)");
        pstmt.setString(1, username); // (these are parameters)
        pstmt.setString(2, passwordHash);
        pstmt.setString(3, email);

        System.out.println(pstmt.toString());

        int updateCount = pstmt.executeUpdate();
        System.out.println("Updated: " + updateCount);

        if (updateCount == 0) return false;
        return true;

    } catch (SQLException e) {
        System.out.println("Error");
        return false;
    }

我已经打印出来的SQL语句并将其复制并粘贴到终端,在那里我打开了数据库的连接并且工作正常(添加了';')。

我知道这不起作用,因为executeUpdate()之后的print语句永远不会打印出来。我在我的代码中的其他地方使用PreparedStatements来检查用户是否在数据库中,并且那些SELECT调用与executeQuery()一起正常工作。

为什么会失败?

编辑:我打印出堆栈跟踪,我收到的错误是我的表中的一个字段没有默认值。这是真的。表中有更多字段用户名/密码哈希/电子邮件,但为什么请求从终端而不是从Java执行得很好? (我正在想,如果我只是指定了可以解决这个问题的默认值,但我想知道是否还有其他方法。)

堆栈追踪:

java.sql.SQLException: Field 'firstname' doesn't have a default value
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4096)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4028)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2490)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2651)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2734)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2375)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2359)
at com.quizzine.database.UserData.createNewAccount(UserData.java:81)
at com.quizzine.login.CreateAccountServlet.doPost(CreateAccountServlet.java:50)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:680)

2 个答案:

答案 0 :(得分:0)

  

我打印出堆栈跟踪,我收到的错误是我的表中的一个字段没有默认值。这是真的。表中还有更多字段用户名/密码哈希/电子邮件,但为什么请求从终端而不是从Java执行得很好?

只要将遗漏的列可以为空或者通过DEFAULT约束指定的默认值,只需将值插入表中的列子集即可。否则,无论是通过控制台还是PreparedStatement运行它,插入语句都将失败。

答案 1 :(得分:0)

java.sql.SQLException: Field 'firstname' doesn't have a default value

异常表示您的列firstname有一个NOT NULL约束,而您在创建表TABLE_NAME时没有给它一个默认值

你可以通过这两种方法解决这个问题,

方法1:

alter "TABEL_NAME" 
add a default value, such as '' to the column "firstname"

或方法2:

    pstmt = con.prepareStatement("INSERT INTO " + TABLE_NAME + " (" + USERNAME + ", " + PASSWORD_HASH + ", " + EMAIL + ", " + FIRST_NAME + ") VALUES (?, ?, ?, '')");      // changed here
    pstmt.setString(1, username); // (these are parameters)
    pstmt.setString(2, passwordHash);
    pstmt.setString(3, email);