3.6 SQLcl LiquibaseおよびDBMS_METADATA Oracle Databaseパッケージによる動的オブジェクト変換

Oracleには、データベース機能を拡張する多数のパッケージ(Oracle Databaseとともに自動的にインストールされる)が用意されています。これらのパッケージの1つであるDBMS_METADATAは、データベース・ディクショナリからメタデータをXMLまたはSQLデータ定義言語(DDL)文として取得し、XMLを発行してオブジェクトを再作成する方法を提供します。

Oracle SQLcl Liquibaseは、DBMS_METADATAパッケージを使用して、データベース・オブジェクトの状態を動的に変換する特殊な変更ログを生成および実行します。これは、Liquibaseオープンソース・クライアントでは使用できません。generate-schemaなどのSQLcl専用のLiquibaseコマンドを使用して、完全なOracleデータベース・スキーマを更新できます。これには、変更ログの仕様に従った、すでに存在する表およびその他のオブジェクトの変更が含まれます。オープンソースのLiquibaseで、既存の表を示す変更ログに対してupdateコマンドを実行すると、失敗します。これは、オープンソースのLiquibaseが既存のオブジェクトを変更できないためです。

generate-schemagenerate-objectなどのコマンドから生成されるSQLcl Liquibaseの特殊な変更ログでは、DBMS_METADATAパッケージのSXMLデータ形式を使用して、これらの動的更新を実行します。SXMLは、SQL DDLをXMLに直接変換するように見えるオブジェクト・メタデータのXML表現です。

この項では、いくつかの例を使用してこの概念を示します。この例では、Windowsベースのオペレーティング・システムが使用されています。

例1

SQLclリリース22.3でOracleデータベースに接続します。この例で紹介されている表には、いくつかのサンプル表が含まれています。この例で使用する表は、employeesとdepartmentsです。

SQL> select table_name from user_tables;

TABLE_NAME
_____________
REGIONS
LOCATIONS
DEPARTMENTS
JOBS
EMPLOYEES
JOB_HISTORY
HIRE_DATE
PERSON_COLLECTION
COUNTRIES

9 rows selected.
  1. SQLcl Liquibaseを使用して、データベース状態のスキーマを生成します。
    SQL> lb generate-schema
    これはコード・スニペットです。
  2. 別のコマンドライン・ウィンドウに切り替えて、オープンソースのLiquibaseクライアントを使用してデータベース状態の変更ログを生成します。generate-schemaは拡張機能を使用するSQLcl専用コマンドであるため、オープンソースのLiquibaseクライアントはgenerate-changelogコマンドを使用する必要があります。

    ノート:

    オープンソースのLiquibaseクライアントをLiquibase Webサイトからダウンロードできます。
    >liquibase --changelog-file=sql_test.xml generate-changelog
    これはコード・スニペットです。

    データベースの状態は、SQLcl LiquibaseとオープンソースのLiquibaseクライアントの両方で取得されるようになりました。

  3. SQLclコマンドライン・ウィンドウで、データベースにいくつか変更を加えます。
    SQL>alter table employees add height number;
    Table EMPLOYEES altered.
    
    SQL>alter table employees add mood varchar2(50);
    Table EMPLOYEES altered.
    
    SQL>alter table departments add happiness varchar2(50);
    Table DEPARTMENTS altered.
    データベース内のこれらの列の追加を表示します。
    SQL> select * from departments;
    SQL> select * from employees;
    これはコード・スニペットです。
  4. データベースを変更ログの状態に変更するには、Liquibase updateコマンドを使用する必要があります。これは、employeesおよびdepartments表に追加の列が追加されていないデータベースの状態です。

    これを行うには、SQLclに接続されておらず、オープンソースのLiquibaseクライアント・コマンドの実行に使用されたコマンドライン・ウィンドウで、次のコマンドを入力します。

    >liquibase --changelog-file=sql_test.xml update
    これはコード・スニペットです。

    Liquibaseが、表などのデータベース内にすでに存在するオブジェクトを検出したため、updateコマンドが失敗します。この標準バージョンのLiquibaseでは、これらのオブジェクトは動的に処理されません。

  5. SQLclコマンドライン・ウィンドウで、同じステップがSQLcl Liquibaseで繰り返されます。

    最初に、update-sqlコマンドを使用してスキーマの更新を完了するために使用されるSQLを確認します。

    SQL>lb update-sql -changelog-file controller.xml
    これはコード・スニペットです。

    出力を確認すると、departments表とemployees表が認識され、作成した追加の列を削除して変更ログの状態に戻す必要があることがわかります。

    これはコード・スニペットです。

    実際により複雑なユースケースでは、多くの場合、SQLのdropコマンドに関連するリスクがあります。update-sqlコマンドを使用してSQLコードを調べると、確認に役立ちます。その後、手動で変更セットを変更し、必要に応じてチェックできます。

    updateコマンドを実行すると、スキーマが正常に更新され、列が削除されます。

    SQL> lb update -changelog-file controller.xml
    --Starting Liquibase at 68:23:55 (version xml 4.15.0 #0 built at 2022-08-19 14:45+0000)
    
    -- Loaded 38 change(s)

例2

この例でも、同じ概念について説明し、今回は列と表を追加します。

この例では、データベース内の表Activitiesが、departments表の列Head_CountRetention、およびemployees表のAwardsとともにすでに作成されています。

これはコード・スニペットです。

変更ログが生成され、Activities表およびHead_countRetentionおよびcolumnsが削除されて、Liquibaseを使用してそれらを作成するように表示されます。

  1. SQLclでスキーマを生成します。

    ノート:

    前述の例の変更ログを別のフォルダに移動して、問題を回避します。
    SQL> lb generate-schema
    --Starting Liquibase at 09:33:52 (version 4.15.0 #0 built at 2022-08-19 14:45+0000)
  2. 別のコマンドライン・ウィンドウに切り替えて、オープンソースのLiquibaseクライアントでコマンドを実行します。ここで、変更ログも生成します。

    >liquibase --changelog-file=sql_test2.xml generate-changelog
    これはコード・スニペットです。
  3. SQLclコマンドライン・ウィンドウで、Activities表およびHead_countRetentionおよびAwards列を削除して、それらの作成をupdateコマンドで確認できるようにします。

    SQL> drop table activities;
    Table ACTIVITIES dropped.
    
    SQL> alter table employees drop column awards;
    Table EMPLOYEES altered.
    
    SQL> alter table departments drop column head_count;
    Table DEPARTMENTS altered.
    
    SQL> alter table departments drop column retention;
    Table DEPARTMENTS altered.
  4. オープンソースのLiquibaseコマンドライン・ウィンドウで、updateコマンドを実行します。

    > liquibase --changelog-file=sql_test2.xml update
    これはコード・スニペットです。

    Liquibaseが既存のオブジェクトを検出すると、更新は失敗します。

  5. SQLclコマンドライン・ウィンドウで、確認するためのSQLを生成し、SQLcl Liquibaseで更新を実行します。

    SQL>lb update-sql -changelog-file controller.xml
    これはコード・スニペットです。

    SQL出力で、Activities表の作成およびSQLcl LiquibaseがSQL文を生成したことに関するセクションを確認し、列を追加するためにDepartments表およびEmployees表を変更できます。

    これはコード・スニペットです。
  6. 更新を実行して、表および列が追加されていることを確認します。

    SQL> lb update -changelog-file controller.xml
    これはコード・スニペットです。
    SQL>select table_name from user_tables;
    SQL>select * from employees;
    SQL>select * from departments;
    
    SQL> select table_name from user_tables;
    
    TABLE_NAME
    _____________
    REGIONS
    LOCATIONS
    DEPARTMENTS
    JOBS
    EMPLOYEES
    JOB_HISTORY
    DATABASECHANGELOG_ACTIONS
    DATABASECHANGELOG
    ACTIVITIES
    COUNTRIES
    
    11 rows selected.
    
    これはコード・スニペットです。