如何从脚本文件创建 HSQL in-memory-db?

Posted

技术标签:

【中文标题】如何从脚本文件创建 HSQL in-memory-db?【英文标题】:How to create a HSQL in-memory-db from script file? 【发布时间】:2015-10-27 08:23:21 【问题描述】:

我在内存中有两个 HSQL 数据库。使用第一个数据库,我创建了耗时的数据库结构和测试数据。该数据库通过SCRIPT 命令导出到一个sql 文件中。我的第二个数据库(不一定在同一个 JVM 中)应该从导出的 sql 文件构建。

public static void main(String[] args) throws Exception 
    try (Connection firstConnection = DriverManager.getConnection("jdbc:hsqldb:mem:connection1", "sa", "")) 
        try (Statement statement = firstConnection.createStatement()) 
            statement.execute("CREATE TABLE table1 (id INT)");
            statement.execute("SCRIPT 'my.script'");
        
    

    try (Connection secondConnection = DriverManager.getConnection("jdbc:hsqldb:mem:connection2", "sa", "")) 
        ScriptUtils.executeSqlScript(secondConnection, new FileSystemResource("my.script"));
    

调用ScriptUtils.executeSqlScript() 时出现以下异常:

Caused by: java.sql.SQLInvalidAuthorizationSpecException: invalid authorization specification - already exists: SA in statement [CREATE USER SA PASSWORD DIGEST 'd41d8cd98f00b204e9800998ecf8427e']
    at org.hsqldb.jdbc.JDBCUtil.sqlException(JDBCUtil.java:327)
    at org.hsqldb.jdbc.JDBCUtil.sqlException(JDBCUtil.java:247)
    at org.hsqldb.jdbc.JDBCStatement.fetchResult(JDBCStatement.java:1817)
    at org.hsqldb.jdbc.JDBCStatement.execute(JDBCStatement.java:638)
    at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:457)
    ... 3 more
Caused by: org.hsqldb.HsqlException: invalid authorization specification - already exists: SA
    at org.hsqldb.error.Error.error(Error.java:83)
    at org.hsqldb.error.Error.error(Error.java:72)
    at org.hsqldb.rights.GranteeManager.addUser(GranteeManager.java:623)
    at org.hsqldb.rights.UserManager.createUser(UserManager.java:115)
    at org.hsqldb.StatementSchema.getResult(StatementSchema.java:1026)
    at org.hsqldb.StatementSchema.execute(StatementSchema.java:268)
    at org.hsqldb.Session.executeCompiledStatement(Session.java:1378)
    at org.hsqldb.Session.executeDirectStatement(Session.java:1248)
    at org.hsqldb.Session.execute(Session.java:1008)
    at org.hsqldb.jdbc.JDBCStatement.fetchResult(JDBCStatement.java:1809)
    ... 5 more

导出现有内存数据库并稍后将其导入另一个(空)内存数据库的正确方法是什么?

【问题讨论】:

【参考方案1】:

SCRIPT 语句创建一个完整的数据库脚本,可以作为文件数据库打开。将第二个数据库作为文件打开:不存储修改的数据库。

Connection secondConnection = DriverManager.getConnection("jdbc:hsqldb:file:my;files_readonly=true", "sa", "")

【讨论】:

我暂时选择了这个解决方案,但我仍然希望有更好的解决方案。 better 解决方案是哪种方式? 我将原始脚本文件复制到临时目录并创建了该复制文件的实例,因为我需要一个可以丢弃的可写版本。 “更好”(对我自己而言)将是一个 mem:数据库,并且该数据库不应该是只读的,所以我可以告诉 HSQL “嘿,让我成为一个 mem:这个脚本文件中的数据库(备份)”。 你错了。只有数据库FILES 是只读的。可以修改数据。初始加载后文件不会被修改。它相当于一个 mem: 数据库,但从脚本加载。【参考方案2】:

问题似乎出在脚本而不是运行它的代码上。

错误在于它试图创建已经存在的 SA 用户 CREATE USER SA(它是您首先通过身份验证运行脚本的用户)。

您应该在脚本中删除(注释掉)该行,然后您应该能够继续前进。

【讨论】:

如果我注释掉 CREATE USER SA 我得到下一个错误。如果我注释掉该行,我会继续出现另一个错误,依此类推。应该有一种方法可以导出数据库并在不进行额外修改的情况下将其导入。

以上是关于如何从脚本文件创建 HSQL in-memory-db?的主要内容,如果未能解决你的问题,请参考以下文章

如何找到Hive提交的SQL相对应的Yarn程序的applicationId

如何从 .NET 应用程序访问 HSQL DB?

liquibase hsql db列创建错误

使用 jdbc:embedded-database 时如何连接到 Spring 创建的 HSQL?

Spring:HSQL-无法执行数据库脚本

如何在 HSQL DB 中创建具有最大行值的序列?