【问题标题】:Parsing csv java [closed]解析csv java [关闭]
【发布时间】:2013-06-10 07:49:15
【问题描述】:

我在用 Java 解析 csv 文件并使用它插入数据库时​​遇到问题。

我正在使用以下代码:

public class CSVLoader {

    private static final 
        String SQL_INSERT = "INSERT INTO ${table}(${keys}) VALUES(${values})";
    private static final String TABLE_REGEX = "\\$\\{table\\}";
    private static final String KEYS_REGEX = "\\$\\{keys\\}";
    private static final String VALUES_REGEX = "\\$\\{values\\}";

    private Connection connection;
    private char seprator;

    /**
     * Public constructor to build CSVLoader object with
     * Connection details. The connection is closed on success
     * or failure.
     * @param connection
     */
    public CSVLoader(Connection connection) {
        this.connection = connection;
        //Set default separator
        this.seprator = '|';
    }

    /**
     * Parse CSV file using OpenCSV library and load in 
     * given database table. 
     * @param csvFile Input CSV file
     * @param tableName Database table name to import data
     * @param truncateBeforeLoad Truncate the table before inserting 
     *          new records.
     * @throws Exception
     */
    public void loadCSV(String csvFile, String tableName,
            boolean truncateBeforeLoad) throws Exception {

        CSVReader csvReader = null;
        if(null == this.connection) {
            throw new Exception("Not a valid connection.");
        }
        try {

            csvReader = new CSVReader(new FileReader(csvFile), '|', '\'', 4);

        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("Error occured while executing file. "
                    + e.getMessage());
        }

        String[] headerRow = csvReader.readNext();

        if (null == headerRow) {
            throw new FileNotFoundException(
                    "No columns defined in given CSV file." +
                    "Please check the CSV file format.");
        }
                System.out.println(headerRow.length);                
        String questionmarks = StringUtils.repeat("?,", headerRow.length);
        questionmarks = (String) questionmarks.subSequence(0, questionmarks
                .length() - 1);

        String query = SQL_INSERT.replaceFirst(TABLE_REGEX, tableName);
        query = query
                .replaceFirst(KEYS_REGEX, StringUtils.join(headerRow, ","));
        query = query.replaceFirst(VALUES_REGEX, questionmarks);

        System.out.println("Query: " + query);
                String[] nextLine;
        Connection con = null;
        PreparedStatement ps = null;
        try {
            con = this.connection;
            con.setAutoCommit(false);
            ps = con.prepareStatement(query);

            if(truncateBeforeLoad) {
                //delete data from table before loading csv
                con.createStatement().execute("DELETE FROM " + tableName);
            }

            final int batchSize = 1000;
            int count = 0;
            Date date = null;

                        while ((nextLine = csvReader.readNext()) != null) {

                if (null != nextLine) {
                    int index = 1;

                                        for ( String string : nextLine) {

                                            date = DateUtil.convertToDate(string);
                        if (null != date) {
                            ps.setDate(index++, new java.sql.Date(date
                                    .getTime()));
                        } else {

                                                      ps.setString(index++, string);



                                                }

                                        }
                    ps.addBatch();

                                }
                if (++count % batchSize == 0) {
                    ps.executeBatch();
                }
            }

                        ps.executeBatch(); // insert remaining records

                        con.commit();
        } catch (Exception e) {
            con.rollback();
            e.printStackTrace();
            throw new Exception(
                    "Error occured while loading data from file to database."
                            + e.getMessage());
        } finally {
            if (null != ps)
                ps.close();
            if (null != con)
                con.close();

            csvReader.close();
        }
    }

    public char getSeprator() {
        return seprator;
    }

    public void setSeprator(char seprator) {
        this.seprator = seprator;
    }


public static void main(String[] args) throws ClassNotFoundException, SQLException, Exception {

   Class.forName("net.sourceforge.jtds.jdbc.Driver");  
  Connection  conn = DriverManager.getConnection("jdbc:jtds:sqlserver://172.16.0.221:1433/tripicker; useNTLMv2; domain=TEST", "root", "");
CSVLoader loader = new CSVLoader(conn);
loader.loadCSV("C:\\lol.csv", "lol", true);

}

}

但是当我测试时它给了我以下异常:

java.sql.BatchUpdateException: 参数 #2 尚未设置。

csv 是这样的:

Generation Date |2013-05-22 17:57:08|||||||
Number of rows |122837|||||||
Idrissi|Youssef
cks|grrrr

我的表的列是 Idrissi 和 youssef。

感谢您的帮助

【问题讨论】:

  • SO 不是代码审查的地方

标签: java sql csv


【解决方案1】:

通过阅读您的代码和您提供的 CSV 文件,您正在考虑的标题行似乎是:

Generation Date |2013-05-22 17:57:08|||||||

所以,当您调用 headerRow.length 时,它将是 9(或者如果最后一列不被认为是空的,则可能是 8)。

因此,当您设置参数时,您将只设置 9 个(或 8 个)必需参数中的 2 个,从而为您提供BatchUpdateException。

有两种方法可以解决这个问题:

  • 删除 CSV 文件的前两行
  • 如果您无法手动编辑 CSV 文件,请添加一些代码以忽略前两行:

    // Skip the first two lines
    if (null==csvReader.readNext() || null==csvReader.readNext()) {
        throw new FileNotFoundException(
            "Unable to skip CSV file headers." +
            "Please check the CSV file format.");
    }
    
    String[] headerRow = csvReader.readNext();
    

    而不是

    String[] headerRow = csvReader.readNext();
    

【讨论】:

  • 我已更改此设置,但它返回错误 2 查询:INSERT INTO 大声笑(java.sql.BatchUpdateException:参数#2 尚未设置我仍然有同样的错误,我认为问题来自csv阅读器的构造函数调用
  • 这里是错误 2 Query: INSERT INTO lol(idrissi,Youssef) Values(?,?)java.sql.BatchUpdateException: Parameter #2 has not been set
  • @Ech-Charif 能否检查一下CSV文件末尾是否有空行,如果有则删除?
  • 不,我曾经验证过,但我的 csv 文件中没有空行
  • @Ech-Charif 你能打印循环中的参数以检查正在设置的内容吗?类似这样的东西:System.out.println(index+" : >" + string + "<");?
猜你喜欢
  • 2010-10-25
  • 2010-09-19
  • 1970-01-01
  • 1970-01-01
  • 2012-07-21
  • 1970-01-01
  • 1970-01-01
  • 2013-02-19
  • 1970-01-01
相关资源
最近更新 更多