首先,我想为标题道歉,但是当我解释时,你会理解为什么我不知道怎么说这个。无论如何,我正在写一个聊天程序,当我给出" UPDATE"命令我跟着我想要更新的字段的名称然后我给我的新值。我的问题是它让我通过一个关于错误列的异常,但我确信在多次检查后我给出的字段名称与我的SQL中的名称相同。我使用MySQL与phpMyAdmin。这是我的代码部分:
客户端:
if (mymessage.equals("UPDATE")) {
String[] arr = input.nextLine().split(" ");
message = id + "-=-" + arr[0].trim() + "-=-" + arr[1].trim();
message2 = encrypt(message, serverAesKey);
write.println(message2);
write.flush();
}
服务器:
if (msg[2].trim().equals("UPDATE")) {
System.out.println("waiting...");
message = read.nextLine();
command = Mediator.decrypt(message, Mediator.getServerAesKey());
System.out.println(command);
msg = command.split("-=-");
int id = Integer.parseInt(msg[0].trim());
String field = msg[1].trim();
String update = msg[2].trim();
System.out.println("....."+id+"-"+field+"-"+update);
Mediator.updateDB(id, field, update); >>this simply runs the method below
public void updateInfo(int id, String field, String update) {
Connection connection;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/chat", "root", "");
switch (field) {
case "name":
String SQLname = "UPDATE info SET name = " + update + " WHERE id = " + id + "";
PreparedStatement pstmtName = connection.prepareStatement(SQLname);
pstmtName.executeUpdate();
break;
case "password":
String SQLpassword = "UPDATE info SET password = " + update + " WHERE id = " + id + "";
PreparedStatement pstmtPwd = connection.prepareStatement(SQLpassword);
pstmtPwd.executeUpdate();
break;
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
这是我得到的例外:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'nick' in 'field list'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1052)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3609)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3541)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2002)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2163)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2624)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2127)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2427)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2345)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2330)
at test.Database.updateInfo(Database.java:122)
at test.Mediator.updateDB(Mediator.java:100)
at test.ServerService.executeService(ServerService.java:108)
at test.ServerService.run(ServerService.java:73)
at java.lang.Thread.run(Thread.java:722)
这是我的输出,您可以看到我的消息被正确分割:
4-=-admin-=-UPDATE
waiting...
4-=-name-=-nick
.....4-name-nick
这是我的数据库:
id|username|password|name|login
3 |user |user |user|0
4 |admin |admin |admin|0
(我想拍一张照片,但我缺乏声誉,但这正是它的写作方式。)
您可以忽略Mediator和加密/解密的任何内容,它们可以正常工作。我想知道的是,当我给出正确的字段时,为什么我会得到和例外。
答案 0 :(得分:1)
基本上,列name
是某种文本数据类型(varchar
等...),因此不是......
String SQLname = "UPDATE info SET name = " + update + " WHERE id = " + id + "";
PreparedStatement pstmtName = connection.prepareStatement(SQLname);
pstmtName.executeUpdate();
问题是,UPDATE info SET name = " + update + " WHERE id = " + id + "
对数据库看起来像UPDATE info SET name = nick WHERE id = 0
...... nick
对数据库意味着什么?我想象的并不是很多。
您应该将值绑定到PreparedStatement
String SQLname = "UPDATE info SET name = ? WHERE id = ?";
PreparedStatement pstmtName = connection.prepareStatement(SQLname);
pstmtName.setString(1, update);
pstmtName.setInt(2, id);
pstmtName.executeUpdate();
通过数据转换(因为驱动程序可以处理大量内容)以及恶意用户可能的SQL注入,这将为您节省很多麻烦
答案 1 :(得分:0)
要确切知道从哪里来的例外情况我建议你放上 System.out.println(SQLname)在:
下String SQLname = "UPDATE info SET name = " + update + " WHERE id = " + id + "";
和 System.out.println(SQLpassword)在:
下String SQLpassword = "UPDATE info SET password = " + update + " WHERE id = " + id + "";
并输入//:
//PreparedStatement pstmtName = connection.prepareStatement(SQLname);
//pstmtName.executeUpdate();
和:
//PreparedStatement pstmtPwd = connection.prepareStatement(SQLpassword);
//pstmtPwd.executeUpdate();
执行你的程序。 SQL查询(SQLpassword和SQLpassword)将打印在控制台上。使用MySQL命令行执行这些查询