【问题标题】:DbUnit NoSuchTableException - Workaround for long table names in OracleDbUnit NoSuchTableException - Oracle 中长表名的解决方法
【发布时间】:2012-07-10 15:55:06
【问题描述】:

我正在使用 dbunit xml 创建一个在多个数据库上运行的测试套件。不幸的是,昨天我发现我们架构中的一些表名超过 30 个字符,并且被截断以供 Oracle 使用。例如,mysql中名为unusually_long_table_name_error的表在Oracle中名为unusually_long_table_name_erro。这意味着我的 dbunit 文件包含像 <unusually_long_table_name_error col1="value1" col2="value2 /> 这样的行。在 Oracle 中运行测试时,这些行会抛出 NoSuchTableException

是否有针对此的程序化解决方法?我真的很想避免为 Oracle 生成特殊的 xml 文件。我查看了一个自定义的MetadataHandler,但它返回了很多我不知道如何拦截/欺骗的java.sql 数据类型。我可以自己读取 xml,将每个表名截断为 30 个字符,将其写入临时文件或StringBufferInputStream,然后将其用作我的 DataSetBuilder 的输入,但这似乎需要很多步骤才能完成。也许有一些具有同义词或存储过程的忍者 Oracle 技巧或天知道什么其他可以帮助我。这些想法之一明显优于其他想法吗?有没有其他的方法会因其简单和优雅而让我大吃一惊?谢谢!

【问题讨论】:

  • 请检查是否可以使用类似于mysql中链接中的包装功能blog.mclaughlinsoftware.com/2011/02/05/…
  • 我从this SO question 及其source link 的理解是,超过30 个字符的同义词由于自动重命名约定而无法使用。存储过程和函数也限制为 30 个字符。所以看来这种方法在这里行不通。
  • 我的意思是在 MYSQL 而不是 ORACLE 中使用类似同义词的东西
  • Mysql已经允许超过30个字符的表名,所以我没有任何问题。我的测试在 Mysql 和 SQL Server 上运行良好,但是 Oracle 有不同的表名(被截断以适应 30 个字符的限制),所以我的 dbunit .xml 文件不能使用它。
  • 我不确定这是否可行,我的意思是在源数据库中创建视图或同义词,表名作为表名的前三十个字符,然后在 oracle 中创建表,表名作为前三十个字符源数据库表,以便您可以导出视图或同义词并将它们作为表导入 oracle

标签: java sql oracle dbunit


【解决方案1】:

鉴于缺乏答案,我最终采用了自己建议的方法,

  1. 读取 .xml 文件
  2. Regex 的表名已经出来了
  3. 如果表名超过 30 个字符,则将其截断
  4. 将(可能修改的)行附加到 StringBuilder
  5. 将该 StringBuilder 馈送到 ByteArrayInputStream 中,适合传递到 DataSetBuilder 中

public InputStream oracleWorkaroundStream(String fileName) throws IOException
{
  String ls = System.getProperty("line.separator");

  // This pattern isolates the table name from the rest of the line
  Pattern pattern = Pattern.compile("(\\s*<)(\\w+)(.*/>)");

  FileInputStream fis = new FileInputStream(fileName);
  // Use a StringBuidler for better performance over repeated concatenation
  StringBuilder sb = new StringBuilder(fis.available()*2);

  InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
  BufferedReader buff = new BufferedReader(isr);
  while (buff.ready())
  {
    // Read a line from the source xml file
    String line = buff.readLine();
    Matcher matcher = pattern.matcher(line);

    // See if the line contains a table name
    if (matcher.matches())
    {
      String tableName = matcher.group(2);
      if (tableName.length() > 30)
      {
        tableName = tableName.substring(0, 30);
      }

      // Append the (potentially modified) line
      sb.append(matcher.group(1));
      sb.append(tableName);
      sb.append(matcher.group(3));
    }
    else
    {
      // Some lines don't have tables names (<dataset>, <?xml?>, etc.)
      sb.append(line);
    }
    sb.append(ls);
  }

  return new ByteArrayInputStream(sb.toString().getBytes("UTF-8"));
}

编辑:从重复的字符串连接切换到 StringBuilder,这提供了巨大的性能提升

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-09
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多