我想从CSV文件创建一个新的嵌入式h2数据库。 这是csv文件的片段
国家,城市,AccentCity,大区,人口,经纬度
广告,aixovall,Aixovall,06,,42.4666667,1.4833333
广告,安道尔,安道尔,07,,42.5,1.5166667
ad,andorra la vella,Andorra la Vella,07,20430,42.5,1.5166667
广告,安道尔-VIEILLE,安道尔-维埃耶,07,,42.5,1.5166667
广告,安道尔,安道尔,07,,42.5,1.5166667
我不想检索csv文件的所有字段。实际上,我想要除 City 和 Region 字段以外的所有字段。
此外,如果 POPULATION 的内容不为空,我想将csv文件的内容插入到数据库中。
因此,在上面的csv示例中,我们必须只将第3行插入到h2表WORLDCITIES中,因为它的'population'字段已被指示。
这是我写的一段代码。但是,正如你所看到的,还不够:
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),种群浮动,纬度浮动,纵向浮动
提前感谢您的帮助。
答案 0 :(得分:10)
您可以在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;
答案 1 :(得分: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.
...`
谢谢!
答案 2 :(得分:2)
使用H2类Csv
的read()
方法,并遍历ResultSet
,在找到所需的行时插入所需的行。