我正在尝试在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)
答案 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);