我的任务是通过jdbc代码将制表符分隔文件加载到psql数据库中。我使用PreparedStatement来执行查询。但是我无法将数据加载到数据库中,我得到了这样的异常“INSERT表达式比目标列多”。我附上了我的代码,请帮帮我。
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class process {
static Connection connection = null;
public static void instertable(String line, Connection connection) {
String values[] = null;
PreparedStatement pst = null;
int i = 0;
try {
pst = connection.prepareStatement("insert into tablename values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
values = line.split("\t");
System.out.println("len" + values.length);
for (i = 0; i <= values.length; i++) {
System.out.println(values[i]);
pst.setString(i + 1, values[i]);
}
System.out.println("ii " + i);
System.out.println("pst " + pst);
pst.executeUpdate();
System.out.println("load data database");
} catch (Exception ex) {
System.out.println("load error:" + ex.getMessage());
}
}
public static void readfile(String FileName, Connection connection) {
BufferedReader bufferedreader = null;
String line = null;
try {
bufferedreader = new BufferedReader(new FileReader(FileName));
while ((line = bufferedreader.readLine()) != null) {
// System.out.println(line);
instertable(line, connection);
}
} catch (Exception ex) {
ex.getMessage();
}
}
public static void main(String[] args) throws IOException {
String FileName = "i.txt";
//String LoadOutput=args[3];
try {
Class.forName("org.postgresql.Driver");
connection = DriverManager.getConnection(
"jdbc:postgresql://127.0.0.1:5432/dbname", "username",
"password");
readfile(FileName, connection);
} catch (SQLException e) {
System.out.println("Connection Failed! Check output console");
e.printStackTrace();
} catch (Exception e) {
System.out.println("Exception message : " + e.getMessage());
}
}
}
答案 0 :(得分:2)
这里有一个错误:
for (i = 0; i <= values.length; i++) {
<=
应为<
:当i
为values.length
时,values[i]
会导致ArrayIndexOutOfBoundsException
被抛出。你在循环中迭代一次太多了。
当抛出ArrayIndexOutOfBoundsException
时,异常消息可能只包含错误索引。这可以解释为什么您将load error: 32
作为自己的信息。
顺便说一下,你在这里部分是你自己糟糕的错误处理的受害者:
catch (Exception ex) {
System.out.println("load error:"+ex.getMessage());
}
您正在捕捉Exception
,这是非常一般的,只显示错误消息。
相反,我建议您抓取SQLException
(通常会有有用的错误消息),而不是Exception
。
最后,您还应关闭PreparedStatement
。在finally
块中执行此操作:
finally {
if (pst != null) {
try {
pst.close();
}
catch (SQLException e) {
System.out.println("Error closing prepared statement: " + e.getMessage());
}
}
}
您编辑的评论证明了下一个问题:
pst = connection.prepareStatement("insert into tablename values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
您收到的消息表明您的表格少于32列,因此无法插入所有数据。我建议将列名添加到INSERT
语句中:
pst = connection.prepareStatement("insert into tablename (column1, column2, ..., column32) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
通过指定列名称,您可以修复列的顺序,并确保如果将来任何列添加到表中,您不会突然收到错误消息。
答案 1 :(得分:0)
信息很明确:还有更多?比表tablename中的列。我建议你总是在insert语句中指定列列表:你也可以通过这种方式控制列的顺序。