-5

我在解析 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。

谢谢你的帮助

4

1 回答 1

2

通过阅读您的代码和您提供的 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();
    
于 2013-06-10T08:43:25.153 回答