java - H2 不删除临时表的序列

标签 java sql h2

我有一个应用程序,我使用 H2 临时表来存储大型缓存。但是当我关闭所有连接并关闭数据库时,我的表的序列不会被删除。一段时间后,我有很多带有随机名称的泄露序列。

问题:

  • 设计时不删除临时表的序列?

  • 我如何找出任何表都没有使用具体序列,以便我可以删除该序列?

这是简单的 junit4 测试:

import org.junit.Test;

import java.io.File;
import java.sql.*;

import static org.junit.Assert.assertEquals;

public class H2Test {
  String databaseUrl = "jdbc:h2:./SST;";
  String userName = "sa";
  String password = "";
  @Test
  public void tempTableTest() throws Exception {
    Class.forName("org.h2.Driver");
    File databaseFile = new File("./SST.mv.db");
    if(databaseFile.exists()){
      databaseFile.delete();
    }

    assertCount("SELECT count(*) FROM INFORMATION_SCHEMA.SEQUENCES", 0);
    assertCount("SELECT count(*) FROM INFORMATION_SCHEMA.TABLES where table_name = 'SST'", 0);

    try (Connection connection = DriverManager.getConnection(databaseUrl, userName, password)) {
      execute(connection, "CREATE CACHED LOCAL TEMPORARY TABLE SST ( id BIGINT IDENTITY, value VARCHAR(2048) NULL)");
      execute(connection, "INSERT INTO sst(value) VALUES('some value')");
      execute(connection, "SHUTDOWN");
    }

    assertCount("SELECT count(*) FROM INFORMATION_SCHEMA.TABLES where table_name = 'SST'", 0);
    assertCount("SELECT count(*) FROM INFORMATION_SCHEMA.SEQUENCES", 0);
  }

  private void assertCount(String query, int count) throws SQLException {
    try (Connection connection = DriverManager.getConnection(databaseUrl, userName, password) ) {
      try (Statement st = connection.createStatement()) {
        ResultSet resultSet = st.executeQuery(query);
        resultSet.next();
        assertEquals(count, resultSet.getInt(1));
        execute(connection, "SHUTDOWN");
      }
    }
  }

  public void execute(Connection connection, String statement) throws SQLException {
    try (Statement st = connection.createStatement()) {
      st.execute(statement);
    }
  }
}

最佳答案

这是 H2 数据库中的一个错误。它将在 H2 版本 1.4.180 中修复。临时表的序列不应存储在数据库文件中。而且它们实际上不会被存储,直到第一次使用它们(作为您案例中 insert 语句的一部分)。

如果您想手动删除该序列,您可以检查它是否在任何表中被引用。一种方法是运行 script nodata 语句,并检查(通过正则表达式匹配)序列是否被引用。

关于java - H2 不删除临时表的序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24475683/

相关文章:

sql - 将 Excel 从 Azure Blob 存储导入到 Sql Server 时出现数据截断问题

java - H2 数据库(嵌入式)连接超时

sql - 从 SQL 脚本在 H2 数据库中插入长文本

java - 是什么导致了 java.lang.ArrayIndexOutOfBoundsException 以及如何防止它?

java - 尝试在 Apache Kylin 中为示例数据构建多维数据集时出现 java.io.FileNotFoundException : File does not exist: hive-exec-2. 1.0.jar 错误

java - 如何将拖动的节点保持在其他节点前面(JavaFX 8)?

mysql - 删除除最新的 50 行以外的所有行

sql - Sqlite获取行中所有不同值的计数

java - 关于 Android 上存储的快速问题

sql - 是否可以在 Oracle 中创建一个不作为主键的标识列,它与 H2 数据库有何关系?