HSQL CSV 文本表正在读取多行的单列

Posted

技术标签:

【中文标题】HSQL CSV 文本表正在读取多行的单列【英文标题】:HSQL CSV text table is reading single column over many lines 【发布时间】:2017-10-19 12:31:24 【问题描述】:

我在使用 HSQL's text tables 时遇到了奇怪的行为

如果带引号的列分隔符是第一列条目,则该行的最后一列条目将过度读取到下一行。

给定一个 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 行读取为:

Col1 : ","

Col2 : "col 2 第 1 行

"第 1 行第 2 行""

第 2 行根本不会被读取。预期的行为是:

第一行:

Col1: ","

Col2: "col 2 第 1 行"

第 2 行:

Col1: "col 1 第 2 行"

Col2: "col 2 第 2 行"

奇怪的是,如果你在带引号的分隔符和 line1 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_quoted=true 使用不同的行尾 CRLF、LF、CR 进行测试。

这些都会导致相同的结果:过度阅读最后一列。除了在带引号的字段分隔符和结束引号之间放置一个空格之外,唯一有效的方法是确保相关列不是第一列。

【问题讨论】:

奇怪的是,如果您在带有分隔符的列之前放置另一列,它可以正常工作,所以我将其用作解决方法。 【参考方案1】:

您需要在文本源设置中指定 all_quoted:

"SET TABLE " + archiveName + " SOURCE 'archive/" + archiveName + ".csv;encoding=UTF-8;all_quoted=true'"

更新:已检查此问题并发现是一个错误。已针对 HSQLDB 版本 2.4.1 修复此问题

【讨论】:

抱歉,忘了提及我已经尝试了所有常见的东西,比如 all_quoted、更改文件编码和检查行尾。这里的问题不在于它将第 1 列第 1 行视为没有引号,而是如果字段分隔符在第一列中,则它会过度读取最后一列。我将编辑我的问题以澄清。

以上是关于HSQL CSV 文本表正在读取多行的单列的主要内容,如果未能解决你的问题,请参考以下文章

在多行表单上关闭键盘 (Pixel2)

GBQ Unpviot Columns 分为单列和多行

如何加载包含多行记录的 CSV 文件?

快速保存多行文本

如何使用 Spring Batch 读取一个单元格中包含多行的 CSV 文件?

使用pandas读取csv文件时如何选择多行?