当我尝试脱机连接Oracle时,无法对脱机数据库执行命令

时间:2018-02-10 10:45:11

标签: mysql oracle offline liquibase

我使用以下代码:

private static String file="create-table.yml";
public static void main(String[] args) throws Exception {
    Database database =createOfflineDatabase("offline:oracle");
    Liquibase liquibase = new Liquibase(file, new ClassLoaderResourceAccessor(), database);
    liquibase.update("test");
    liquibase.dropAll();
}

private static Database createOfflineDatabase(String url) throws Exception {
    DatabaseConnection databaseConnection = new OfflineConnection(url, new ClassLoaderResourceAccessor());
    return DatabaseFactory.getInstance().openDatabase(url, null, null, null, null);
}

获得此例外:

Exception in thread "main" liquibase.exception.MigrationFailedException: Migration failed for change set create-table.yml::create-table.yml::vishwakarma:
 Reason: liquibase.exception.DatabaseException: Cannot execute commands against an offline database
at liquibase.changelog.ChangeSet.execute(ChangeSet.java:619)
at liquibase.changelog.visitor.UpdateVisitor.visit(UpdateVisitor.java:51)
at liquibase.changelog.ChangeLogIterator.run(ChangeLogIterator.java:79)
at liquibase.Liquibase.update(Liquibase.java:214)
at liquibase.Liquibase.update(Liquibase.java:192)
at liquibase.Liquibase.update(Liquibase.java:188)
at liquibase.Liquibase.update(Liquibase.java:181)
at com.test.liquibase.LiquibaseTest.main(LiquibaseTest.java:27)

我做错了什么或遗失了什么?请帮忙。

先谢谢

2 个答案:

答案 0 :(得分:1)

离线数据库是Liquibase提供的,允许您生成SQL以更新liquibase用户无法直接更新的数据库 - 它们无法更新。有关脱机数据库的更多详细信息,请参阅this documentation

答案 1 :(得分:1)

您正在使用的Liquibase类(在大多数示例代码中)似乎没有“ updateSQL”。您可以以编程方式调用main方法,并传入必要的--url参数,以使其完成工作。例如:

        liquibase.integration.commandline.Main.main(new String[]{"--changeLogFile=src/test/resources/db.changelog.xml"
                ,"--outputFile=target/updateSql.txt"
                ,"--url=offline:unknown?outputLiquibaseSql=true"
                , "updateSQL"});

将生成:

-- *********************************************************************
-- Update Database Script
-- *********************************************************************
-- Change Log: src/test/resources/db.changelog.xml
-- Ran at: 12/04/20 11:51
-- Against: null@offline:unknown?outputLiquibaseSql=true
-- Liquibase version: 3.8.9
-- *********************************************************************

CREATE TABLE DATABASECHANGELOG (ID VARCHAR(255) NOT NULL, AUTHOR VARCHAR(255) NOT NULL, FILENAME VARCHAR(255) NOT NULL, DATEEXECUTED datetime NOT NULL, ORDEREXECUTED INT NOT NULL, EXECTYPE VARCHAR(10) NOT NULL, MD5SUM VARCHAR(35), DESCRIPTION VARCHAR(255), COMMENTS VARCHAR(255), TAG VARCHAR(255), LIQUIBASE VARCHAR(20), CONTEXTS VARCHAR(255), LABELS VARCHAR(255), DEPLOYMENT_ID VARCHAR(10));

-- Changeset src/test/resources/db.changelog.xml::createTable-example::liquibase-docs
CREATE TABLE public.person (address VARCHAR(255));

INSERT INTO DATABASECHANGELOG (ID, AUTHOR, FILENAME, DATEEXECUTED, ORDEREXECUTED, MD5SUM, DESCRIPTION, COMMENTS, EXECTYPE, CONTEXTS, LABELS, LIQUIBASE, DEPLOYMENT_ID) VALUES ('createTable-example', 'liquibase-docs', 'src/test/resources/db.changelog.xml', CURRENT_TIMESTAMP, 1, '8:49e8eb557129b33d282c4ad2fdc5d4d9', 'createTable tableName=person', '', 'EXECUTED', NULL, NULL, '3.8.9', '6688703163');

并还输出一个databasechangelog.csv,以跟踪随后运行的DATABASECHANGELOG的状态。

如果您编辑代码以使用不同的ID装入带有新内容的“ db.changelog2.xml”,并告诉它将sql写出到仅设置了第二个更改的新文件中。这是因为databasechangelog.csv将用于知道以前运行的内容。然后,下一次将更新CSV:

"ID","AUTHOR","FILENAME","DATEEXECUTED","ORDEREXECUTED","EXECTYPE","MD5SUM","DESCRIPTION","COMMENTS","TAG","LIQUIBASE","CONTEXTS","LABELS","DEPLOYMENT_ID"
"createTable-example","liquibase-docs","src/test/resources/db.changelog.xml","2020-04-12T12:10:16.989","2","EXECUTED","8:49e8eb557129b33d282c4ad2fdc5d4d9","createTable tableName=person","","","3.8.9","()","","6689816939"
"createTable-example2","liquibase-docs","src/test/resources/db.changelog2.xml","2020-04-12T12:26:56.664","4","EXECUTED","8:3740614394b969eeb1edcc9fd0187bdb","createTable tableName=person2",,"","3.8.9","()","","6690816645"

警告::似乎,如果直接调用main方法,它将在内部调用System.exit(),因此,如果您真的想在工具中运行updateSQL,则需要查看该主类中的代码以弄清楚如何在不使JVM被System.exit()终止的情况下进行操作。