【问题标题】:How to create a h2 database from some fields of a CSV file如何从 CSV 文件的某些字段创建 h2 数据库
【发布时间】:2011-07-06 19:09:43
【问题描述】:

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

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

ad,aixovall,Aixovall,06,,42.4666667,1.4833333

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

ad,andorra la vella,Andorra la Vella,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 字段之外,我都想要它们。

此外,我只想将 csv 文件的内容插入数据库,前提是 POPULATION 的内容不为空。

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

这是我编写的代码的 sn-p。但是,正如您所见,这还不够:

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)、人口浮点数、纬度浮点数、经度浮点数

提前感谢您的帮助。

【问题讨论】:

    标签: java database csv h2


    【解决方案1】:

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

    【讨论】:

    • @Thomas Mueller:感谢您对此发表评论;你的方法更好。
    【解决方案2】:

    最后,我按照您的建议进行了此操作。 我只放了我认为与问题更相关的代码部分:)

    `

    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.
    

    ....`

    谢谢!

    【讨论】:

    • @Thomas Mueller 的例子更简洁。 INSERT 也可以使用类似的方法。
    【解决方案3】:

    您可以在 CREATE TABLE as documented 中添加列定义,并将其与 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;
    

    【讨论】:

    • 非常感谢,最后我确实使用了你的解决方案!
    猜你喜欢
    • 2023-03-23
    • 2021-04-10
    • 2011-04-12
    • 1970-01-01
    • 2016-09-27
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 1970-01-01
    相关资源
    最近更新 更多