Sql H2-如何截断所有表?

Sql H2-如何截断所有表?,sql,database,h2,Sql,Database,H2,我假设有一种方法可以从代码中实现这一点,至少有一些好的解决方法 请考虑,我不想删除所有表(我见过这个命令),只是为了从它们删除行,但是保持现有的模式和所有约束。 也许我可以从元数据中获得所有表的列表,并分别对每个表应用TRUNCATE命令?但是他们的关系和外键呢 有什么想法吗 现在,我想出了这个解决方案。。。但仍然需要对其进行更彻底的测试 private void truncateDatabase () throws SQLException { String tempDir = Sys

我假设有一种方法可以从代码中实现这一点,至少有一些好的解决方法

请考虑,我不想删除所有表(我见过这个命令),只是为了从它们删除行,但是保持现有的模式和所有约束。 也许我可以从元数据中获得所有表的列表,并分别对每个表应用TRUNCATE命令?但是他们的关系和外键呢


有什么想法吗

现在,我想出了这个解决方案。。。但仍然需要对其进行更彻底的测试

private void truncateDatabase () throws SQLException {
    String tempDir = System.getProperty("java.io.tmpdir");
    File tempRestoreFile = new File(tempDir + File.separator + "tempRestore");
    Connection connection = dataSource.getConnection(); 
    Statement statement = connection.createStatement();
    statement.execute("SCRIPT SIMPLE NODATA DROP TO '" + tempRestoreFile + "' CHARSET 'UTF-8'");
    statement.execute("RUNSCRIPT FROM '" + tempRestoreFile.getAbsolutePath() + "' CHARSET 'UTF-8'");
}

您可以这样做:

  • 使用禁用引用完整性

  • 使用获取所有表的列表

  • 使用从每个表中删除数据

  • 使用启用引用完整性

下面是一个
截断所有表的示例,该示例禁用外键,然后截断当前架构中的所有表,然后重新启用外键:

DROP ALIAS IF EXISTS truncate_all_tables;
CREATE ALIAS truncate_all_tables AS $$
    void truncateAllTables(Connection conn) throws SQLException {
        conn.createStatement().executeUpdate("SET FOREIGN_KEY_CHECKS=0");
        ResultSet rs = conn.createStatement().
            executeQuery("SELECT table_name FROM information_schema.tables WHERE table_schema = SCHEMA()");
        while (rs.next()) {
            String tableName = rs.getString(1);
            conn.createStatement().executeUpdate("TRUNCATE TABLE \"" + tableName + "\" RESTART IDENTITY");
        }
        conn.createStatement().executeUpdate("SET FOREIGN_KEY_CHECKS=1");
    }
$$;

CALL truncate_all_tables();
或者,您可以在代码中定义函数:

public class H2Functions {
  public static void truncateAllTables(Connection conn) throws SQLException {
    conn.createStatement().executeUpdate("SET FOREIGN_KEY_CHECKS=0");
    ResultSet rs = conn.createStatement().
      executeQuery("SELECT table_name FROM information_schema.tables WHERE table_schema = SCHEMA()");
    while (rs.next()) {
      String tableName = rs.getString(1);
      conn.createStatement().executeUpdate("TRUNCATE TABLE \"" + tableName + "\" RESTART IDENTITY");
    }
    conn.createStatement().executeUpdate("SET FOREIGN_KEY_CHECKS=1");
  }
}
然后用作别名:

SET MODE REGULAR;
CREATE ALIAS IF NOT EXISTS truncate_all_tables FOR "com.yourcompany.H2Functions.truncateAllTables";
CALL truncate_all_tables();
SET MODE MySQL;
这里我添加了
SET MODE
语句作为示例,如果在MySQL模式下使用H2,则必须切换回H2模式,然后声明函数,然后切换回MySQL模式


不幸的是,
truncate_all_表
不会重置auto_inc列。有关详细信息,请参阅。

以下是截断所有表的工作Java代码:

public void truncate()引发SQLException{
try(Connection=dataSource.getConnection();
PreparedStatement setChecks=connection.prepareStatement(“SET FOREIGN\u KEY\u CHECKS=?”;
PreparedStatement getTables=connection.prepareStatement(“从信息\u schema.tables中选择表\u名称,其中表\u schema=schema()”){
try(ResultSet tables=getTables.executeQuery()){
setChecks.setBoolean(1,false);
setChecks.executeUpdate();
while(tableRes.next()){
String table=tableRes.getString(1);
try(PreparedStatement truncateTable=connection.prepareStatement(“TRUNCATE TABLE”+TABLE+“RESTART IDENTITY”)){
truncateTable.executeUpdate();
}
}
}最后{
setChecks.setBoolean(1,true);
setChecks.executeUpdate();
}
}
}

存在一个
截断表tableName RESTART IDENTITY
。我尝试了H2 v199,但RESTART IDENTITY不起作用。顺便说一句,H2语法表没有提到截断唯一提到的地方是@EvgenijRyazanov,而且最好有一个内置函数来截断所有表,除了一些静态表(如国家):这对测试非常有用。有关该命令,请参阅。如果您可以使用RESTART IDENTITY重现问题,并为其构建独立的测试用例(没有第三方依赖项),那么您真的应该在GitHub上提交一份bug报告: