Java MySQL插入错误?
我正在写一个程序,跟踪当地企业的销售情况。我编写了一个方法,将一个表导出到一个csv文件中,然后立即将该csv文件加载到一个新表中进行归档;但是,当它在方法archive()中运行时,它只会在while循环中运行一次,但在第二个循环中运行时,它会出现以下错误:Java MySQL插入错误?,java,mysql,jdbc,Java,Mysql,Jdbc,我正在写一个程序,跟踪当地企业的销售情况。我编写了一个方法,将一个表导出到一个csv文件中,然后立即将该csv文件加载到一个新表中进行归档;但是,当它在方法archive()中运行时,它只会在while循环中运行一次,但在第二个循环中运行时,它会出现以下错误: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'N' in 'field list' at sun.reflect.NativeCons
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'N' 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:2618)
at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1749)
at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1666)
at serverarchiver.ServerGui.archive(ServerGui.java:118)
at serverarchiver.ServerGui.run(ServerGui.java:144)
at java.lang.Thread.run(Thread.java:722)
以下是相关代码:
public void archive(){
try {
//Archive and new table
stmt.executeQuery("SELECT * INTO OUTFILE '"+ getMonth()+"" + getYear() + ".csv' FIELDS TERMINATED BY ',' FROM last");
stmt.executeUpdate("CREATE TABLE `lastdb`.`"+ getMonth()+"" + getYear() + "` (`Name` VARCHAR(50) NOT NULL ,`Goal` INT NOT NULL ,`New` INT NOT NULL , `Used` INT NOT NULL , `Total` INT NOT NULL , `Pace` INT NOT NULL ,PRIMARY KEY (`Name`, `Goal`, `New`, `Used`, `Total`, `Pace`) );");
CSVReader reader = new CSVReader(new FileReader("C:/ProgramData/MySQL/MySQL Server 5.5/data/lastdb/"+getMonth()+"" + cal.getInstance().get(Calendar.YEAR) + ".csv"));
String[] nextLine;
while((nextLine = reader.readNext()) != null){
stmt.executeUpdate("INSERT INTO `lastdb`.`"+ getMonth()+"" + cal.getInstance().get(Calendar.YEAR) + "` (`Name`, `Goal`, `New`, `Used`, `Total`, `Pace`) VALUES ('"+ nextLine[0]+ "', " +nextLine[1]+ " , " +nextLine[2]+ " , " +nextLine[3]+ " , " +nextLine[4]+ " , " +nextLine[5]+ ")");
}
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException ed){
ed.printStackTrace();
}catch(SQLException eds){
eds.printStackTrace();
}
}
这只能由正在读取的CSV文件的SQL注入攻击引起 换句话说,将SQL字符串与未验证的CSV值连接在一起可能会导致SQL字符串格式错误。我建议在执行填充的SQL字符串之前对其执行
System.out.println()
,以便您可以检查到底是什么导致SQL查询无效
您可以通过相应地转义CSV值来修复它,但最好的解决方案是使用PreparedStatement
而不是Statement
。例如
preparedStatement = connection.prepareStatement("INSERT INTO `lastdb`.`" + getMonth() + "" + cal.getInstance().get(Calendar.YEAR)
+ "` (`Name`, `Goal`, `New`, `Used`, `Total`, `Pace`) VALUES (?, ?, ?, ?, ?, ?)");
while ((nextLine = reader.readNext()) != null) {
// ...
preparedStatement.setString(1, nextLine[0]);
preparedStatement.setString(2, nextLine[1]);
preparedStatement.setString(3, nextLine[2]);
preparedStatement.setString(4, nextLine[3]);
preparedStatement.setString(5, nextLine[4]);
preparedStatement.setString(6, nextLine[5]);
preparedStatement.executeUpdate();
}
它不仅可以转义列值,还可以提高性能。您甚至可以通过使用批来进一步改进它,方法是addBatch()
和executeBatch()
另见:
RENAME TABLE last TO lastdb.<month><year>;
CREATE TABLE last LIKE lastdb.<month><year>;
将表最后重命名为lastdb。;
像lastdb一样创建表last。;
这将是闪电般的快,更安全 您能告诉我们您的sql查询在执行时是如何显示的吗?对不起,我还是MySQL新手,您希望看到什么?具体行的完整查询。因此,在执行查询时,将变量替换为它们的值sprint this before
stmt.executeUpdate
String query=“INSERT INTO
lastdb
”+getMonth()+“+cal.getInstance().get(Calendar.YEAR)+`(Name
,Goal
,New
,Used
,Total
,Pace
)值(“+nextLine[0]+”,“+nextLine[1]+”,“+nextLine[2]+”,“+nextLine[3]+”,“+nextLine[4]+,“+nextLine[5]+”)`OHHH!好的,谢谢大家,给我一分钟……我现在就做。
RENAME TABLE last TO lastdb.<month><year>;
CREATE TABLE last LIKE lastdb.<month><year>;