我在HSQL的文本表中遇到了奇怪的行为
如果带引号的列分隔符是第一个列条目,则该行的最后一个列条目将被复读到下一行。
给定一个用创建的2列文本表
statement.executeUpdate("CREATE TEXT TABLE " + archiveName + " ("
+ "message varchar(1000),"
+ "line varchar(1000))");
csv文件为:
",","col 2 line 1"
"col 1 line 2","col 2 line 2"
它将第1行读取为:
第1列:",">
第2列:"第2列第1行
"第1列第2行">
第2行将完全不被读取。预期行为为:
第1行:
第1列:",">
第2列:"第2列第1行">
第2行:
第1列:"第1列第2行">
第2列:"第2列第2行">
奇怪的是,如果你在第1行col1的引号分隔符和右引号之间放一个空格,它会正确读取文件:
", ","col 2 line 1"
"col 1 line 2","col 2 line 2"
要复制,请创建提到的csv文件并运行以下命令:
public void schemaCheck() {
final String archiveName = "test";
Connection connection;
try {
connection = DriverManager.getConnection("jdbc:hsqldb:file:test", "SA", "");
try (Statement statement = connection.createStatement()) {
statement.executeUpdate("DROP TABLE IF EXISTS " + archiveName);
statement.executeUpdate("CREATE TEXT TABLE " + archiveName + " ("
+ "message varchar(1000),"
+ "line varchar(1000))");
statement.executeUpdate("SET TABLE " + archiveName + " SOURCE 'archive/" + archiveName + ".csv;encoding=UTF-8'");
} catch (SQLException e) {
throw new IllegalStateException(e);
}
try (PreparedStatement statement = connection
.prepareStatement("SELECT * FROM " + archiveName)) {
ResultSet result = statement.executeQuery();
while (result.next()) {
System.out.println("Line:");
System.out.println("First col:");
System.out.println(result.getString(1));
System.out.println("Second col:");
System.out.println(result.getString(2));
}
} catch (SQLException e) {
throw new IllegalStateException(e);
}
} catch (SQLException e1) {
throw new IllegalStateException(e1);
}
}
这是使用HSQLDB v2.4.0
我尝试过的东西:
- 确保表上的编码参数与csv文件的编码匹配
- 设置all_quote=true
- 使用不同的线路末端CRLF、LF、CR进行测试
这些都会导致相同的结果:过度阅读最后一列。除了在带引号的字段分隔符和右引号之间放一个空格之外,唯一有效的方法是确保有问题的列不是第一列。
您需要在文本源设置中指定all_quoted:
"SET TABLE " + archiveName + " SOURCE 'archive/" + archiveName + ".csv;encoding=UTF-8;all_quoted=true'"
更新:已检查此问题,发现它是一个错误。HSQLDB版本2.4.1已修复