2011-03-01 9 views
8

me gustaría crear una nueva base de datos h2 incrustada desde un archivo CSV. Aquí es el fragmento del archivo csvCómo crear una base de datos h2 desde algunos campos de un archivo CSV

País, Ciudad, AccentCity, Región, Población, Latitud, Longitud

anuncio, Aixovall, Aixovall, 06,, 42.4666667,1.4833333

anuncio, Andorra, Andorra, 07,, 42.5,1.5166667

anuncio, Andorra la Vella, Andorra la Vella, 07,20430,42.5,1.5166667

anuncio, Andorra-vieille, Andorra-Vieille, 07,, 42.5, 1.5166667

anuncio, Andorra, Andorra, 07,, 42.5,1.5166667

no quiero para recuperar todos los campos del archivo CSV. En realidad, los quiero a todos, excepto los campos Ciudad y Región.

Y además, quiero insertar el contenido del archivo csv en la base de datos SÓLO SI el contenido de POBLACIÓN no está vacío.

Por lo tanto, en el ejemplo csv anterior, solo debemos insertar la tercera fila en la tabla h2 WORLDCITIES porque se indica su campo 'población'.

Aquí hay un fragmento de código que escribí. Pero, como se puede ver, no es suficiente todavía:

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')); 

Y si he entendido bien, CSVREAD crear los campos utilizando el tipo VARCHAR, pero quiero las cosas como esta:

PAÍS VARCHAR (3), ACCENTCITY VARCHAR (40), POPLOATION FLOAT, LATITUDE FLOAT, LONGITUDE FLOAT

Gracias de antemano por su ayuda.

Respuesta

9

Puede agregar las definiciones de columna en CREATE TABLE asdocumented y combinar esto con una cláusula WHERE. Tenga en cuenta el uso de CREATE TABLE AS SELECT es un poco más rápido que por separado CREATE TABLE e INSERT INTO (no estoy seguro si la velocidad es muy importante para usted):

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; 
+1

¡Muchas gracias, finalmente utilicé su solución! – paissad

2

utilizan el método de la clase H2 Csvread() y repite el proceso del ResultSet, insertando las filas deseadas como las encuentras.

+0

Es posible, pero es una gran cantidad de código para escribir . –

+0

@Thomas Mueller: Gracias por comentar sobre esto; tu enfoque es mejor – trashgod

3

finalmente, procedí de esta manera mientras aconsejaba. Yo sólo puse las partes del código que creo que está más relacionada con la pregunta :)

`

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. 

....`

Gracias!

+0

@Thomas El ejemplo de Mueller es más sucinto. Un enfoque similar se puede usar con [INSERT] (http://h2database.com/html/grammar.html#insert) también. – trashgod

Cuestiones relacionadas