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报告: