从文件流导入H2 CSV

时间:2014-07-31 17:23:32

标签: java jdbc h2

我目前正在使用批量CSVREAD将大型CSV文件导入H2:

logger.info("create param table");
templ.execute(paramsTable + " AS SELECT * FROM CSVREAD('" + consoleArgs.paramDataFile + "','FID,MEANING,VALUE,HID');");

但是为了优化存储,我们将压缩CSV文件。因此我需要先解压缩文件。由于我们不想存储解压缩文件,因此将未压缩的char流直接输入H2会很好。有什么想法吗?

1 个答案:

答案 0 :(得分:3)

我可能只是使用PreparedStatement手动插入数据,而不使用CSV文件。

或者,您可以自己使用the CSV tool(它允许从阅读器中读取)。

您可以创建一个返回表格的user defined function(请参阅文档中的“使用函数作为表格”),例如在那里使用CSV工具(或以您自己的方式生成数据,没有CSV)。返回结果集的函数示例:

CREATE ALIAS MY_CSV AS $$
import org.h2.tools.*;
import java.sql.*;
@CODE
ResultSet getCsv(Connection conn, String fileName)
        throws SQLException {
    SimpleResultSet rs = new SimpleResultSet();
    rs.addColumn("A", Types.INTEGER, 10, 0);
    String url = conn.getMetaData().getURL();
    if (url.equals("jdbc:columnlist:connection")) {
        return rs;
    }
    rs.addRow(1);
    return rs;
}
$$;

然后使用该函数创建表:

CREATE TABLE TEST 
AS SELECT A FROM MY_CSV('fileName');    

H2将调用该方法3次:

  • 在准备阶段,在解析查询时,验证它在语法上是否正确。它在这里检索列名,并检查其中一个是“A”。这很快。
  • 在执行阶段,检索列名和数据类型。从理论上讲,这个调用不是必需的,因为自第一次调用以来没有任何改变。但是,请注意这是再次只检索列名称(URL再次为jdbc:columnlist:connection)。这很快。
  • 在执行阶段,检索实际数据。在这种情况下,网址为jdbc:default:connection。这是缓慢的部分。