gpt4 book ai didi

java - MySQL 插入错误?

转载 作者:行者123 更新时间:2023-11-29 14:39:38 25 4
gpt4 key购买 nike

我正在编写一个程序来跟踪本地企业的销售情况。我编写了一种方法,将表导出到 csv 文件,然后将该 csv 文件加载到新表中以进行存档;但是,当它运行 archive() 方法时,它只会运行一次 while 循环,可以工作,但在第二次循环时会出现以下错误:

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 注入(inject)攻击引起的。

换句话说,您在其中与未经验证的 CSV 值连接的 SQL 字符串可能会导致 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() 进行批处理来进一步改进它。

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.addBatch();
}

preparedStatement.executeBatch();

另请参阅:

关于java - MySQL 插入错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8247836/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com