H2 - 如何截断所有表格?

时间:2014-11-20 17:14:31

标签: sql database h2

我认为有一种方法可以通过代码执行此操作,至少是一些好的解决方法。

请考虑我不想删除所有表(我已经看过这个命令),只是为了删除它们中的行,但保留现有的模式和所有约束。

也许我可以以某种方式从元数据中获取所有表的列表并分别为每个表应用TRUNCATE命令?但是他们的关系和外键呢?

任何想法?

4 个答案:

答案 0 :(得分:21)

你可以这样做:

答案 1 :(得分:2)

目前,我提出了这个解决方案......但仍需要更彻底地测试它。

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'");
}

答案 2 :(得分:0)

以下是stored procedure truncate_all_tables的示例,该示例禁用外键,然后截断当前模式中的所有表,然后启用外键:

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_tables不会重置auto_inc列。有关详细信息,请参见Spring test with H2 in memory database truncate all tables

答案 3 :(得分:0)

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

public void truncate() throws SQLException {
    try (Connection connection = dataSource.getConnection();
         PreparedStatement setChecks = connection.prepareStatement("SET FOREIGN_KEY_CHECKS = ?");
         PreparedStatement getTables = connection.prepareStatement("SELECT table_name FROM information_schema.tables WHERE table_schema = SCHEMA()")) {
        try (ResultSet tablesRes = getTables.executeQuery()) {
            setChecks.setBoolean(1, false);
            setChecks.executeUpdate();
            while (tablesRes.next()) {
                String table = tablesRes.getString(1);
                try (PreparedStatement truncateTable = connection.prepareStatement("TRUNCATE TABLE " + table + " RESTART IDENTITY")) {
                    truncateTable.executeUpdate();
                }
            }
        } finally {
            setChecks.setBoolean(1, true);
            setChecks.executeUpdate();
        }
    }
}