1

我正在尝试使用 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() 之后的打印语句永远不会被打印。我在代码的其他地方使用 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)
4

2 回答 2

0

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

只要被遗漏的列可以为空或者它们具有通过DEFAULT约束指定的默认值,只需将值插入表中的列子集就可以了。否则,无论是通过控制台还是PreparedStatement.

于 2012-12-03T04:29:46.700 回答
0
java.sql.SQLException: Field 'firstname' doesn't have a default value

异常意味着您的列firstname有一个NOT NULL约束,并且您在创建表时没有给它一个默认值TABLE_NAME

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

方法一:

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);
于 2017-01-20T08:59:06.757 回答