8

我想从 CSV 文件创建一个新的嵌入式 h2 数据库。这是csv文件的片段

国家、城市、口音城市、地区、人口、纬度、经度

广告,aixovall,Aixovall,06,,42.4666667,1.4833333

ad,andorra,Andorra,07,,42.5,1.5166667

广告,安道尔城,安道尔城,07,20430,42.5,1.5166667

ad,andorra-vieille,Andorra-Vieille,07,,42.5,1.5166667

ad,andorre,Andorre,07,,42.5,1.5166667

我不想检索 csv 文件的所有字段。实际上,我想要它们,除了CityRegion字段。

此外,我想仅当POPULATION的内容不为空时才将 csv 文件的内容插入数据库。

因此,在上面的 csv 示例中,我们必须只将第 3 行插入到 h2 表 WORLDCITIES 中,因为它的“人口”字段已被指示。

这是我写的一段代码。但是,如您所见,这还不够:

conn = DriverManager.getConnection(connectionURL, connectionProps);
Statement stmt = conn.createStatement();
stmt.execute("CREATE TABLE WORLDCITIES"
        + " AS SELECT COUNTRY, ACCENTCITY, POPULATION, LATITUDE, LONGITUDE"
        + " FROM CSVREAD('snippet.csv'));

如果我理解正确,CSVREAD 使用 VARCHAR 类型创建字段,但我想要这样的东西:

COUNTRY VARCHAR(3)、ACCENTCITY VARCHAR(40)、人口浮点数、纬度浮点数、经度浮点数

提前感谢您的帮助。

4

3 回答 3

10

您可以按照 文档说明在 CREATE TABLE 中添加列定义,并将其与 WHERE 子句结合使用。请注意,使用 CREATE TABLE AS SELECT 比单独的 CREATE TABLE 和 INSERT INTO 语句快一点(不确定速度对您是否非常重要):

CREATE TABLE WORLDCITIES(
  COUNTRY VARCHAR(3), 
  ACCENTCITY VARCHAR(40), 
  POPULATION FLOAT, 
  LATITUDE FLOAT, 
  LONGITUDE FLOAT)
AS SELECT 
  COUNTRY, 
  ACCENTCITY, 
  POPULATION, 
  LATITUDE, 
  LONGITUDE
FROM CSVREAD('snippet.csv') 
WHERE POPULATION IS NOT NULL;
于 2011-03-02T05:27:46.427 回答
3

最后,我按照你的建议这样做了。我只放了我认为与问题更相关的代码部分:)

`

private final String createTableString = ""
    + "CREATE TABLE IF NOT EXISTS " + _tableName
    + " ("
    + "id INT UNSIGNED NOT NULL AUTO_INCREMENT, "
    + "country VARCHAR(3) NOT NULL, "
    + "city VARCHAR(40) NOT NULL, "
    + "region VARCHAR (5) NOT NULL, "
    + "population FLOAT NOT NULL, "
    + "latitude FLOAT NOT NULL, "
    + "longitude FLOAT NOT NULL, "
    + "PRIMARY KEY(id)"
    + " );";

private final String insertString = ""
    + "INSERT INTO " + _tableName
    + " (country, city, region, population, latitude, longitude) "
    + "VALUES (?,?,?,?,?,?)"
    + ";";

public void go() throws IOException, SQLException {

    loadDriver();
    Connection conn = null;
    Properties connectionProps = new Properties();
    connectionProps.put("user", "");
    connectionProps.put("password", "");
    String connectionURL = _protocol + _subprotocol + _dbName + _dbSettings;
    ResultSet rs = null;

    try {
        conn = DriverManager.getConnection(connectionURL, connectionProps);
        logger.info("Connected to {} database.", _dbName);

        conn.setAutoCommit(false);
        Savepoint savept1 = conn.setSavepoint();

        Statement stmt = conn.createStatement();
        try {
            stmt.execute(createTableString);
            logger.info("The table '{}' created successfully", _tableName);
        } catch (SQLException sqle) {
            logger.error("Error while creating the table '{}'", _tableName);
            printSQLException(sqle);
        }

        PreparedStatement pstmt = conn.prepareStatement(insertString);
        _allStatements.add(pstmt);
        /* rs:                           pstmt:
         * 1 -> COUNTRY                  
         * 2 -> CITY                     1 -> COUNTRY
         * 3 -> ACCENTCITY               2 -> CITY
         * 4 -> REGION                   3 -> REGION
         * 5 -> POPULATION               4 -> POPULATION
         * 6 -> LATITUDE                 5 -> LATITUDE
         * 7 -> LONGITUDE                6 -> LONGITUDE
         */
        rs = Csv.getInstance().read(_csvFileName, null, _csvCharset);
        int rowCount = 0;
        while (rs.next()) {
            if (rs.getFloat(5) != 0) { // If population is not null.
                pstmt.setString(1, rs.getString(1)); // country
                pstmt.setString(2, rs.getString(3)); // city (accentcity in reality)
                pstmt.setString(3, rs.getString(4)); // region
                pstmt.setFloat(4, rs.getFloat(5));   // population
                pstmt.setFloat(5, rs.getFloat(6));   // latitude
                pstmt.setFloat(6, rs.getFloat(7));   // longitude
                pstmt.addBatch();
                rowCount ++;
            }
        }
        int[] rowsUpdated = pstmt.executeBatch();
        for (int i=0; i<rowsUpdated.length; i++) {
            if (rowsUpdated[i] == -2) {
                logger.error("Execution {}: unknown number of rows inserted.", i);
                logger.error("Rolling back ...");
                conn.rollback(savept1);
            } else {
                logger.trace("Successful: execution {}, {} rows updated !", i, rowsUpdated[i]);
            }
        }
        conn.commit();
    }
    finally { // release all open resources to avoid unnecessary memory usage.

......`

谢谢!

于 2011-03-02T05:02:20.917 回答
2

使用read()H2 类的方法Csv,并遍历ResultSet,在找到所需的行时插入它们。

于 2011-03-01T20:30:36.537 回答