2024年12月6日金曜日

Autonomous Database上のワークスペースをSQLclのProjectコマンドを使ってローカルのAPEX環境にコピーする

SQLclの24.3よりprojectコマンドが追加されました。このコマンドによりSQLclで接続したOracle Databaseから、データベース・オブジェクトをGitで管理できる形式(つまりテキスト)でエクスポートできます。また、エクスポートした情報からデータベースに適用可能なアーティファクトを生成することができます。データベースからエクスポートする内容は、表やパッケージのDDLの他に、APEXのアプリケーションも含めることができます。

最近のASK TOMのOffice Hourにて、SQLclの開発者とOracle CorporationでAPEXを使ってアプリケーションを開発している方(APEX自体の開発者ではない)が、SQLclのprojectコマンドとその使い方を紹介しています。

SQLcl Projects: CI/CD Make Easy for APEX
https://youtu.be/EM3_2Dd3LOs

ここで紹介されているSQLclのprojectコマンドを使って、Always FreeのAutonomous DatabaseにあるAPEXのワークスペースを、手元のPCに作成したAPEX環境にコピーしてみます。APEXのアプリケーションだけでなく表やデータもコピーの対象とします。表やデータについてはdatapumpを使うと確実ですが、手間がかかるので、Autonomous DatabaseのスキーマをREST対応SQLでアクセスできるように構成し、REST APIを呼び出してデータをコピーします。

SQLclに関する情報は以下のリンクより参照できます。SQLclの最新版もダウンロードできます。


以下の作業を行います。
  1. Autonomous Databaseに新規でREST対応SQLが有効なスキーマを作成する。
  2. REST対応SQLが有効なスキーマをOAuth2で保護する。
  3. 作成したスキーマに紐づけてAPEXワークスペースを作成する。
  4. APEXワークスペースに表やアプリケーションを作成する。
  5. 手元のPCにAPEXの環境を作成する。
  6. SQLclでAutonomous Databaseに接続し、projectコマンドを実行して表やAPEXアプリケーションをエクスポートする。その後、エクスポートした内容からアーティファクトを作成し、ローカルの環境に適用する。
  7. Autonomous Database上のデータを、REST対応SQL経由でローカルの環境にコピーする。
今回の記事では、SQLclで作業することにより、自動化の検討の参考になるようにします。


REST対応SQLが有効なスキーマの作成 - Autonomous Database



Autonomous Databaseに管理者ユーザーADMINで接続し、以下のコマンドを実行します。

パスワードの部分は適切な値に置き換えます。データベース・ユーザの作成に続けて、データベース・ユーザーのREST対応有効にしています。

後でAPEXのワークスペースとしてMYPROJを作成する予定です。そのため、デフォルト・パーシング・スキーマとなるスキーマ名をWKSP_MYPROJとしています。また、p_url_mapping_patternはAPEXのワークスペース名と一致するように、myprojとしています。
create user wksp_myproj identified by "パスワード";

grant connect, resource to wksp_myproj;

begin
    ords_admin.enable_schema(
        p_enabled => TRUE,
        p_schema => 'WKSP_MYPROJ',
        p_url_mapping_type => 'BASE_PATH',
        p_url_mapping_pattern => 'myproj',
        p_auto_rest_auth=> true
    );
    commit;
end;
/

alter user wksp_myproj quota unlimited on data;
この作業は以上で完了です。


OAuthユーザーの作成 - Autonomous Database



作成したデータベース・ユーザーWKSP_MYPROJでAutonomous Databaseに接続し、OAuthユーザーを作成します。作成したOAuthユーザーにロールSQL Developerを割り当てることにより、作成したOAuthユーザーによりREST対応SQLを認証できます。

OAuthユーザーの名前はrestsqluserとします。以下のスクリプトを実行します。引数p_support_emailは適切な値に置き換えます。
begin
    -- create oauth user
    oauth.create_client(
        p_name             => 'restsqluser'
        ,p_grant_type      => 'client_credentials' -- default
        ,p_support_email   => 'yuNN@dummy.com'
        ,p_privilege_names => null
    );
    -- assign SQL Developer role
    oauth.grant_client_role(
        p_client_name => 'restsqluser'
        ,p_role_name  => 'SQL Developer' 
    );
    commit;
end;
/
以上でOAuthユーザーrestsqluserが作成されます。

OAuthでの認証に使用するBearerトークンの取得に使用するクライアントIDクライアント・シークレットを、ビューUSER_ORDS_CLIENTSを検索して確認します。

以下のSELECT文を実行します。

select client_id, client_secret from user_ords_clients where name = 'restsqluser'

SQL> select client_id, client_secret from user_ords_clients where name = 'restsqluser';


CLIENT_ID                   CLIENT_SECRET               

___________________________ ___________________________ 

pOi**************PdC7w..    kUZN**************jlG-Q..    


SQL> 


確認のため、このクライアントIDクライアント・シークレットより、Bearerトークンを取得します。クライアントIDやクライアント・シークレットの末尾にピリオドがついていることがありますが、これらもクライアントIDやクライアント・シークレットの一部なので、省略はしないようにします。

URLのmyprojの部分はスキーマをREST対応にしたときに、p_url_mapping_patternに与えた値(手順と異なる値を指定していたら)に置き換えます。

curl -X POST -u [クライアントID]:[クライアント・シークレット] --data "grant_type=client_credentials" https://[ホスト名]/ords/myproj/oauth/token

% curl -X POST -u pOi************PdC7w..:kUZN***************jlG-Q.. --data "grant_type=client_credentials" https://***********-apexdev.adb.us-ashburn-1.oraclecloudapps.com/ords/myproj/oauth/token

{"access_token":"70cd734q-IcDJpAsIk3n5Q","token_type":"bearer","expires_in":3600}


JSONのレスポンスにaccess_tokenが含まれます。このトークンを使って、REST対応SQLの呼び出しを認証します。REST対応SQLを呼び出し、"select sysdate from dual"を実行します。

先ほど取得したアクセス・トークンは、Authorizationヘッダーの値として、Bearerに続けて入力します。

curl -X POST -H "Authorization: Bearer [access_token]" -H "Content-Type: application/sql" --data-binary "select sysdate from dual" https://[ホスト名]/ords/myproj/_/sql

応答にSYSDATEの値が含まれていれば、OAuthによる保護は完了です。

% curl -X POST -H "Authorization: Bearer 70cd734q-IcDJpAsIk3n5Q" -H "Content-Type: application/sql" --data-binary "select sysdate from dual" https://bp9ncf74sqibu4p-apexdev.adb.us-ashburn-1.oraclecloudapps.com/ords/myproj/_/sql

{"env":{"defaultTimeZone":"UTC"},"items":[{"statementId":1,"statementType":"query","statementPos":{"startLine":1,"endLine":2},"statementText":"select sysdate from dual","resultSet":{"metadata":[{"columnName":"SYSDATE","jsonColumnName":"sysdate","columnTypeName":"DATE","columnClassName":"java.sql.Timestamp","precision":7,"scale":0,"isNullable":1}],"items":[{"sysdate":"2024-12-06T05:07:28Z"}],"hasMore":false,"limit":10000,"offset":0,"count":1},"response":[],"result":0}]} 




APEXワークスペースの作成 - Autonomous Database



Autonomous Databaseに管理者ユーザーADMINで接続し、以下のスクリプトにいくつか引数を渡して実行します。
set echo on

define WKSPNAME  = &1
define ADMINNAME = &2
define ADMINPASS = &3
define ADMINMAIL = &4

begin

-- assign all required roles to default parsing schema
for c1 in (
    select privilege from sys.dba_sys_privs
    where grantee = 'APEX_GRANTS_FOR_NEW_USERS_ROLE'
)
loop
    execute immediate 'grant ' || c1.privilege || ' to wksp_&WKSPNAME';
end loop;

-- add new workspace to apex instance
apex_instance_admin.add_workspace(
    p_workspace => '&WKSPNAME',
    p_primary_schema => 'WKSP_&WKSPNAME'
);

-- set current session to the created workspace.
apex_util.set_workspace('&WKSPNAME');

-- create admin account.
apex_util.create_user(
    p_user_name                    => '&ADMINNAME',
    p_web_password                 => '&ADMINPASS',
    p_developer_privs              => 'ADMIN:CREATE:DATA_LOADER:EDIT:HELP:MONITOR:SQL',
    p_email_address                => '&ADMINMAIL',
    p_default_schema               => 'WKSP_&WKSPNAME',
    p_change_password_on_first_use => 'N'
);
end;
/
commit;

-- assign admin password
create user &ADMINNAME identified by "&ADMINPASS";

exit;

第1引数は作成するAPEXのワークスペース名(今回の作業ではMYPROJとしています)、第2引数はワークスペースの管理者ユーザー名第3引数パスワード第4引数は管理者のメールアドレスを与えます。

@03_create_workspace MYPROJ MYPROJADM [パスワード] [メールアドレス]

SQL> @03_create_workspace MYPROJ MYPROJADM My********Eac noreply@oracle.com

SQL> 

SQL> define WKSPNAME  = &1

SQL> define ADMINNAME = &2

SQL> define ADMINPASS = &3

SQL> define ADMINMAIL = &4

SQL> 

SQL> begin

  2  

  3  -- assign all required roles to default parsing schema

  4  for c1 in (

  5      select privilege from sys.dba_sys_privs

  6      where grantee = 'APEX_GRANTS_FOR_NEW_USERS_ROLE'

  7  )

  8  loop

  9      execute immediate 'grant ' || c1.privilege || ' to wksp_&WKSPNAME';

 10  end loop;

 11  

 12  -- add new workspace to apex instance

 13  apex_instance_admin.add_workspace(

 14      p_workspace => '&WKSPNAME',

 15      p_primary_schema => 'WKSP_&WKSPNAME'

 16  );

 17  

 18  -- set current session to the created workspace.

 19  apex_util.set_workspace('&WKSPNAME');

 20  

 21  -- create admin account.

 22  apex_util.create_user(

 23      p_user_name                    => '&ADMINNAME',

 24      p_web_password                 => '&ADMINPASS',

 25      p_developer_privs              => 'ADMIN:CREATE:DATA_LOADER:EDIT:HELP:MONITOR:SQL',

 26      p_email_address                => '&ADMINMAIL',

 27      p_default_schema               => 'WKSP_&WKSPNAME',

 28      p_change_password_on_first_use => 'N'

 29  );

 30  end;

 31  /

旧:begin


-- assign all required roles to default parsing schema

for c1 in (

    select privilege from sys.dba_sys_privs

    where grantee = 'APEX_GRANTS_FOR_NEW_USERS_ROLE'

)

loop

    execute immediate 'grant ' || c1.privilege || ' to wksp_&WKSPNAME';

end loop;


-- add new workspace to apex instance

apex_instance_admin.add_workspace(

    p_workspace => '&WKSPNAME',

    p_primary_schema => 'WKSP_&WKSPNAME'

);


-- set current session to the created workspace.

apex_util.set_workspace('&WKSPNAME');


-- create admin account.

apex_util.create_user(

    p_user_name                    => '&ADMINNAME',

    p_web_password                 => '&ADMINPASS',

    p_developer_privs              => 'ADMIN:CREATE:DATA_LOADER:EDIT:HELP:MONITOR:SQL',

    p_email_address                => '&ADMINMAIL',

    p_default_schema               => 'WKSP_&WKSPNAME',

    p_change_password_on_first_use => 'N'

);

end;


新:begin


-- assign all required roles to default parsing schema

for c1 in (

    select privilege from sys.dba_sys_privs

    where grantee = 'APEX_GRANTS_FOR_NEW_USERS_ROLE'

)

loop

    execute immediate 'grant ' || c1.privilege || ' to wksp_MYPROJ';

end loop;


-- add new workspace to apex instance

apex_instance_admin.add_workspace(

    p_workspace => 'MYPROJ',

    p_primary_schema => 'WKSP_MYPROJ'

);


-- set current session to the created workspace.

apex_util.set_workspace('MYPROJ');


-- create admin account.

apex_util.create_user(

    p_user_name                    => 'MYPROJADM',

    p_web_password                 => 'My*********ac',

    p_developer_privs              => 'ADMIN:CREATE:DATA_LOADER:EDIT:HELP:MONITOR:SQL',

    p_email_address                => 'noreply@oracle.com',

    p_default_schema               => 'WKSP_MYPROJ',

    p_change_password_on_first_use => 'N'

);

end;


PL/SQLプロシージャが正常に完了しました。


SQL> commit;


コミットが完了しました。


SQL> 

SQL> -- assign admin password

SQL> create user &ADMINNAME identified by "&ADMINPASS";

旧:create user &ADMINNAME identified by "&ADMINPASS"

新:create user MYPROJADM identified by "My*******ac"


User MYPROJADMは作成されました。


SQL> 

SQL> exit;

Oracle Database 23ai Enterprise Edition Release 23.0.0.0.0 - Production

Version 23.6.0.24.11から切断されました

ynakakoshi@Ns-Macbook Projects % 


スクリプトが正常終了すると、ワークスペースMYPROJとその管理者ユーザーMYPROJADMが作成されています。

Autonomous DatabaseのAPEXはオンプレのAPEX環境とは異なり、ユーザー認証時に管理者ユーザーと同名のデータベース・ユーザーのパスワードにより認証します。そのため、APEXのapex_util.create_userだけではなく、データベース・ユーザーとしてもユーザーMYPROJADMを作成しています。

ローカルのAPEX環境を作成する際に、ここで作成したワークスペースのワークスペースIDを指定します。ワークスペースIDを確認するために、以下のSELECT文を実行します。

select workspace_id from apex_workspaces where workspace = 'MYPROJ';

SQL> select workspace_id from apex_workspaces where workspace = 'MYPROJ';


         WORKSPACE_ID 

_____________________ 

   118415045107961267 


SQL> 



表やAPEXアプリケーションの作成 - Autonomous Database



作成したワークスペースMYPROJにサインインし、確認に使用する表などのデータベース・オプジェクトやAPEXアプリケーションを作成します。

ワークスペース作成時に作成した管理者ユーザーMYPROJADMでサインインします。


今回はサンプル・データセットのEMP/DEPTをインストールし、アプリケーションの作成までを行います。

SQLワークショップユーティリティサンプル・データセットを開きます。


EMP/DEPTインストールをクリックします。


ダイアログが開きます。以下では言語として英語を選択していますが、日本語を選択しても良いでしょう。スキーマはデフォルト・パーシング・スキーマのWKSP_MYPROJです。

へ進みます。


データセットのインストールを実行します。


サンプル・データセットEMP/DEPTがインストールされます。継続して、アプリケーションの作成をクリックします。


アプリケーション作成ウィザードが起動します。

そのまま変更せず、アプリケーションの作成を実行します。


アプリケーションが作成されます。

アプリケーションを実行し、動作について確認します。


現在のところワークスペースMYPROJには管理者ユーザーMYPROJADMしかいないので、アプリケーションにMYPROJADMでサインインします。


アプリケーションのホーム・ページが開きます。


以上でAPEXワークスペースおよびスキーマに、移行の対象となる表やAPEXアプリケーションが作成できました。


APEX環境の作成 - ローカル



以前に書いた以下の記事に沿って、手元のPC(私の環境はARM版Mac)にAPEXが動作する環境を作成します。

podmanを使ってOracle Database FreeとOracle REST Data Servicesをコンテナとして実行する

config_apex.shに引数が未指定の場合、データベースのSYSのパスワードはoracle、APEXの管理者パスワードはWelcome_1になります。
git clone https://github.com/ujnak/apex-podman-setup
cd apex-podman-setup
sh config_apex.sh
config_apex.shの実行が正常に終了すると、APEXの環境が作成されています。作成された内容については、元記事を参照してください。

 apex-podman-setup % sh config_apex.sh 

/opt/homebrew/bin/podman

/Users/ynakakoshi/sqlcl/bin/sql

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

                                 Dload  Upload   Total   Spent    Left  Speed

100  276M  100  276M    0     0  32.4M      0  0:00:08  0:00:08 --:--:-- 35.1M

APEX VERSION detected:  24.1.0 APEX_240100

oradata

ords_config

Pod:

0db5f2b11e3e723dac746abfa09bee9b5f7d21f2ac58b1e8fe0bbc6cd6be4bee

Containers:

56b0925f5192dbca28141f53feede9c71ae1d2173a7061cf9216ba859e4783d4

560e19bc3c0cb1f42b4f60c82cbf3bf887837fffdaef9a3c5ad97e8cd9248fbb


The Oracle base remains unchanged with value /opt/oracle


SQL*Plus: Release 23.0.0.0.0 - Production on Fri Dec 6 06:12:31 2024

Version 23.5.0.24.07


Copyright (c) 1982, 2024, Oracle.  All rights reserved.



Connected to:

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.5.0.24.07


SQL> 

User altered.


SQL> 



[省略]


ORDS: Release 24.3 Production on Fri Dec 06 06:17:51 2024


Copyright (c) 2010, 2024, Oracle.


Configuration:

  /etc/ords/config


The global setting named: standalone.http.port was set to: 8181


apex

 apex-podman-setup % 


apex-podman-setupに含まれているcreate_workspace_with_id.sqlを実行し、Autonomous Databaseに作成したワークスペースMYPROJと同じワークスペース名ワークスペースIDを持つワークスペースMYPROJを作成します。

スクリプトの第5引数としてワークスペースIDを与えます。

作成したローカル環境にSQLclで接続します。

sql sys/oracle@localhost/freepdb1 as sysdba

接続したのち、以下を実行します。

@create_workspace_with_id MYPROJ MYPROJADM [パスワード] [メールアドレス] [ワークスペースID]

 apex-podman-setup % sql sys/oracle@localhost/freepdb1 as sysdba



SQLcl: 金 12月 06 15:22:52 2024のリリース24.3 Production


Copyright (c) 1982, 2024, Oracle.  All rights reserved.


接続先:

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.5.0.24.07


SQL> @create_workspace_with_id MYPROJ MYPROJADM My*********ac noreply@oracle.com 118415045107961267

SQL> 

SQL> define WKSPNAME  = &1

SQL> define ADMINNAME = &2

SQL> define ADMINPASS = &3

SQL> define ADMINMAIL = &4

SQL> define WKSPID    = &5

SQL> 

SQL> -- create default parsing shema for worksapce apexdev.

SQL> create user wksp_&WKSPNAME default tablespace users temporary tablespace temp quota unlimited on users;

旧:create user wksp_&WKSPNAME default tablespace users temporary tablespace temp quota unlimited on users

新:create user wksp_MYPROJ default tablespace users temporary tablespace temp quota unlimited on users


User WKSP_MYPROJは作成されました。


SQL> 

SQL> begin

  2  

  3  for c1 in (

  4      select privilege from sys.dba_sys_privs

  5      where grantee = 'APEX_GRANTS_FOR_NEW_USERS_ROLE'

  6  )

  7  loop

  8      execute immediate 'grant ' || c1.privilege || ' to wksp_&WKSPNAME';

  9  end loop;

 10  

 11  apex_instance_admin.add_workspace(

 12      p_workspace_id => &WKSPID,

 13      p_workspace => '&WKSPNAME',

 14      p_primary_schema => 'WKSP_&WKSPNAME'

 15  );

 16  

 17  apex_util.set_workspace('&WKSPNAME');

 18  

 19  apex_util.create_user(

 20      p_user_name                    => '&ADMINNAME',

 21      p_web_password                 => '&ADMINPASS',

 22      p_developer_privs              => 'ADMIN:CREATE:DATA_LOADER:EDIT:HELP:MONITOR:SQL',

 23      p_email_address                => '&ADMINMAIL',

 24      p_default_schema               => 'WKSP_&WKSPNAME',

 25      p_change_password_on_first_use => 'N'

 26  );

 27  end;

 28  /

旧:begin


for c1 in (

    select privilege from sys.dba_sys_privs

    where grantee = 'APEX_GRANTS_FOR_NEW_USERS_ROLE'

)

loop

    execute immediate 'grant ' || c1.privilege || ' to wksp_&WKSPNAME';

end loop;


apex_instance_admin.add_workspace(

    p_workspace_id => &WKSPID,

    p_workspace => '&WKSPNAME',

    p_primary_schema => 'WKSP_&WKSPNAME'

);


apex_util.set_workspace('&WKSPNAME');


apex_util.create_user(

    p_user_name                    => '&ADMINNAME',

    p_web_password                 => '&ADMINPASS',

    p_developer_privs              => 'ADMIN:CREATE:DATA_LOADER:EDIT:HELP:MONITOR:SQL',

    p_email_address                => '&ADMINMAIL',

    p_default_schema               => 'WKSP_&WKSPNAME',

    p_change_password_on_first_use => 'N'

);

end;


新:begin


for c1 in (

    select privilege from sys.dba_sys_privs

    where grantee = 'APEX_GRANTS_FOR_NEW_USERS_ROLE'

)

loop

    execute immediate 'grant ' || c1.privilege || ' to wksp_MYPROJ';

end loop;


apex_instance_admin.add_workspace(

    p_workspace_id => 118415045107961267,

    p_workspace => 'MYPROJ',

    p_primary_schema => 'WKSP_MYPROJ'

);


apex_util.set_workspace('MYPROJ');


apex_util.create_user(

    p_user_name                    => 'MYPROJADM',

    p_web_password                 => 'My************ac',

    p_developer_privs              => 'ADMIN:CREATE:DATA_LOADER:EDIT:HELP:MONITOR:SQL',

    p_email_address                => 'noreply@oracle.com',

    p_default_schema               => 'WKSP_MYPROJ',

    p_change_password_on_first_use => 'N'

);

end;


PL/SQLプロシージャが正常に完了しました。


SQL> commit;


コミットが完了しました。


SQL> exit;

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.5.0.24.07から切断されました

 apex-podman-setup % 


以上でローカルのAPEX環境にワークスペースMYPROJが作成できました。

データベース・ユーザーWKSP_MYPROJで接続できるようにパスワードを設定します。ローカル環境に先ほどと同様にSYSで接続し、以下のコマンドを実行します。

alter user wksp_myproj identified by "パスワード";

SQL> alter user wksp_myproj identified by "My**********ac";


User WKSP_MYPROJが変更されました。


SQL> 


ワークスペースにサインインしてみます。



APEXの開発ツールが開きます。

今の所は、表もAPEXアプリケーションも何もない状態です。



SQLclのprojectコマンドを使った環境のコピー



SQLclのprojectコマンドを使って、Autonomous DatabaseからローカルのDBへ環境をコピーします。

SQLclのユーザー・ガイドの以下のセクションに記載されている手順に従います。

SQLcl User's Guide Release 24.3
4.4 Examples

4.4.1のSingle Schemaのシナリオでは、Oracle Databaseのサンプル・スキーマに含まれるHRをコピーの対象としてデータベースにインストールしています。本記事ではHRの代わりにスキーマWKSP_MYPROJとAPEXのワークスペースMYPROJを作成し、 それらをコピーの対象としています。

最初に空のディレクトリmyprojを作成し、移動します。これ以降の作業は、このディレクトリ上で実施します。

mkdir myproj
cd myproj

SQCclのドキュメントのExamplesではproject initのオプションに-makerootを与えることにより、プロジェクトの名前と同じディレクトリを作成しているので、少しだけ手順は変えています。

% mkdir myproj

% cd myproj

myproj % 


SQLclを起動し、Autonomous DatabaseのスキーマWKSP_MYPROJに接続します。

sql -cloudconfig [ウォレット・ファイル] wksp_myproj/[パスワード]@TNS接続先

myproj % sql -cloudconfig ~/Documents/Wallets/Wallet_APEXDEV.zip wksp_myproj/My********Eac@apexdev_low



SQLcl: 金 12月 06 15:47:49 2024のリリース24.3 Production


Copyright (c) 1982, 2024, Oracle.  All rights reserved.


接続先:

Oracle Database 23ai Enterprise Edition Release 23.0.0.0.0 - Production

Version 23.6.0.24.11


SQL> 


これ以降の作業はほぼExamplesと同じです。実行するコマンドの詳しい解説は、SQLclのドキュメントを参照してください。

project initを実行し、SQLclのデータベース・プロジェクトを作成します。名前はmyprojとします。

project init -name myproj -schemas wksp_myproj

SQL> project init -name myproj -schemas wksp_myproj


------------------------

PROJECT DETAILS

------------------------

Project name:    myproj 

Schema(s):       WKSP_MYPROJ 

Directory:       /Users/yn*******hi/Documents/Projects/myproj 

Connection name:  

Project root:     myproj

Your project has been successfully created

SQL> 


Gitのリポジトリを初期化します。今回の作業ではローカル・リポジトリは作成しますが、GitHubやGitLabにリポジトリは作成しません。SQLclのprojectコマンドの実行にGitのローカル・リポジトリは必須ですが、今回は環境をコピーするだけなのでGitHubへの登録は不要です。

!git init --initial-branch=main
!git add .
!git commit -m "chore: initializing repository with default project files"

SQL> !git init --initial-branch=main

Initialized empty Git repository in /Users/ynakakoshi/Documents/Projects/myproj/.git/


SQL> !git add .


SQL> !git commit -m "chore: initializing repository with default project files"

[main (root-commit) 384bbc1] chore: initializing repository with default project files

 9 files changed, 200 insertions(+)

 create mode 100644 .dbtools/filters/project.filters

 create mode 100644 .dbtools/project.config.json

 create mode 100644 .dbtools/project.sqlformat.xml

 create mode 100644 .gitignore

 create mode 100644 README.md

 create mode 100644 dist/README.md

 create mode 100644 dist/install.sql

 create mode 100644 src/README.md

 create mode 100644 src/database/README.md


SQL> 


ブランチbase-releaseを作成し、Autonomous Databaseから表やAPEXアプリケーションをプロジェクトmyprojにエクスポートします。エクスポートしたファイル(src以下にエクスポートされる)をブランチに追加します。

!git checkout -b base-release
project export
!git status
!git add src

project exportの実行により、表などを作成するDDLやAPEXアプリケーションのエクスポートがファイルとして作成されます。

エクスポートする対象を特定のオブジェクトやアプリケーションに限定するために、-oオプションが使用できます。

SQL> !git checkout -b base-release

Switched to a new branch 'base-release'


SQL> project export

The current connection (description=(retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=adb.us-ashburn-1.oraclecloud.com))(connect_data=(service_name=bp9ncf74sqibu4p_apexdev_low.adb.oraclecloud.com))(security=(ssl_server_dn_match=yes))) WKSP_MYPROJ will be used for all operations

*** INDEXES ***

*** TABLES ***

*** VIEWS ***

*** REF_CONSTRAINTS ***

*** APEX_APPLICATION ***

Exporting Workspace MYPROJ - application 221:Demonstration - EMP / DEPT

-------------------------------

TABLE                         2

APEX_APPLICATION              1

REF_CONSTRAINT                2

INDEX                         2

VIEW                          1

-------------------------------

Exported 8 objects

Elapsed 86 sec

SQL> !git status

On branch base-release

Untracked files:

  (use "git add <file>..." to include in what will be committed)

src/database/wksp_myproj/


nothing added to commit but untracked files present (use "git add" to track)


SQL> !git add src


SQL>


再度ステータスを確認し、エクスポートされたファイルをコミットします。

!git status
!git commit -m "chore: base export of WKSP_MYPROJ schema"


SQL> !git status

On branch base-release

Changes to be committed:

  (use "git restore --staged <file>..." to unstage)

new file:   src/database/wksp_myproj/apex_apps/f221/f221.sql

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/f221.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/page_groups.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p00000.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p00001.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p00002.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p00003.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p00004.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p00005.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p00006.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p09999.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10000.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10010.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10020.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10030.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10031.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10032.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10033.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10034.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10035.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10036.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10040.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10041.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10042.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10043.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10044.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10050.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10051.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10053.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10054.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10060.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10061.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p20000.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p20010.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/acl_roles.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/app_static_files.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/authentications.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/authorizations.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/breadcrumbs.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/build_options.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/lists.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/lovs.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/plugins.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/breadcrumb_templates.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/button_templates.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/classic_report_templates.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/field_templates.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/global_template_options.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/legacy_calendar_templates.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/list_templates.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/page_templates.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/popup_lov_templates.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/region_templates.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/template_option_groups.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/universal_theme.yaml

new file:   src/database/wksp_myproj/apex_apps/f221/readable/workspace/credentials.yaml

new file:   src/database/wksp_myproj/indexes/emp_1.sql

new file:   src/database/wksp_myproj/indexes/emp_2.sql

new file:   src/database/wksp_myproj/ref_constraints/emp_dept_fk.sql

new file:   src/database/wksp_myproj/ref_constraints/emp_mgr_fk.sql

new file:   src/database/wksp_myproj/tables/dept.sql

new file:   src/database/wksp_myproj/tables/emp.sql

new file:   src/database/wksp_myproj/views/emp_dept_v.sql



SQL> !git commit -m "chore: base export of WKSP_MYPROJ schema"

[base-release 20ced9b] chore: base export of WKSP_MYPROJ schema

 63 files changed, 66559 insertions(+)

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/f221.sql

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/f221.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/page_groups.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p00000.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p00001.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p00002.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p00003.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p00004.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p00005.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p00006.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p09999.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10000.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10010.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10020.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10030.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10031.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10032.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10033.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10034.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10035.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10036.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10040.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10041.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10042.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10043.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10044.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10050.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10051.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10053.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10054.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10060.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p10061.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p20000.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/pages/p20010.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/acl_roles.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/app_static_files.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/authentications.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/authorizations.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/breadcrumbs.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/build_options.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/lists.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/lovs.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/plugins.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/breadcrumb_templates.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/button_templates.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/classic_report_templates.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/field_templates.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/global_template_options.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/legacy_calendar_templates.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/list_templates.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/page_templates.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/popup_lov_templates.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/region_templates.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/template_option_groups.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/application/shared_components/theme_42/universal_theme.yaml

 create mode 100644 src/database/wksp_myproj/apex_apps/f221/readable/workspace/credentials.yaml

 create mode 100644 src/database/wksp_myproj/indexes/emp_1.sql

 create mode 100644 src/database/wksp_myproj/indexes/emp_2.sql

 create mode 100644 src/database/wksp_myproj/ref_constraints/emp_dept_fk.sql

 create mode 100644 src/database/wksp_myproj/ref_constraints/emp_mgr_fk.sql

 create mode 100644 src/database/wksp_myproj/tables/dept.sql

 create mode 100644 src/database/wksp_myproj/tables/emp.sql

 create mode 100644 src/database/wksp_myproj/views/emp_dept_v.sql


SQL> 


project stageを実行し、base-releaseをインストールするための(mainブランチと比較した)チェンジログを生成します。

project stage
!git status
!find dist/releases/next

SQL> project stage


Stage is Comparing:

Old Branch refs/heads/main

New Branch refs/heads/base-release





Stage successfully created, please review and commit your changes to repository


SQL> !git status

On branch base-release

Untracked files:

  (use "git add <file>..." to include in what will be committed)

dist/releases/

dist/utils/


nothing added to commit but untracked files present (use "git add" to track)


SQL> !find dist/releases/next

dist/releases/next

dist/releases/next/release.changelog.xml

dist/releases/next/changes

dist/releases/next/changes/base-release

dist/releases/next/changes/base-release/code

dist/releases/next/changes/base-release/code/_custom

dist/releases/next/changes/base-release/wksp_myproj

dist/releases/next/changes/base-release/wksp_myproj/ref_constraint

dist/releases/next/changes/base-release/wksp_myproj/ref_constraint/emp_mgr_fk.sql

dist/releases/next/changes/base-release/wksp_myproj/ref_constraint/emp_dept_fk.sql

dist/releases/next/changes/base-release/wksp_myproj/table

dist/releases/next/changes/base-release/wksp_myproj/table/emp.sql

dist/releases/next/changes/base-release/wksp_myproj/table/dept.sql

dist/releases/next/changes/base-release/wksp_myproj/index

dist/releases/next/changes/base-release/wksp_myproj/index/emp_2.sql

dist/releases/next/changes/base-release/wksp_myproj/index/emp_1.sql

dist/releases/next/changes/base-release/stage.changelog.xml

dist/releases/next/code

dist/releases/next/code/code.changelog.xml

dist/releases/next/code/wksp_myproj

dist/releases/next/code/wksp_myproj/view

dist/releases/next/code/wksp_myproj/view/emp_dept_v.sql


SQL> 


project releaseを実行し、実施した変更をリリースします。

project release -version 1.0 -verbose

SQL> project release -version 1.0 -verbose

Creating a release version 1.0 for the current body of work


Updated change:dist/releases/main.changelog.xml

Moved folder "dist/releases/next" to "dist/releases/1.0"

Created file:  dist/releases/next

Created change:dist/releases/next/release.changelog.xml

Created change:dist/releases/next/release.changelog.xml

Process completed successfully

SQL> 


今回のリリース(Version 1.0)で適用される変更はdist/releases/1.0以下にまとめられています。project gen-artifactを実行し、アーティファクトとしてzipファイルを作成します。

このアーティファクトのzipファイルを、ローカルのAPEX環境に適用します。

!find dist/releases/1.0
project gen-artifact

SQL> !find dist/releases/1.0

dist/releases/1.0

dist/releases/1.0/release.changelog.xml

dist/releases/1.0/changes

dist/releases/1.0/changes/base-release

dist/releases/1.0/changes/base-release/code

dist/releases/1.0/changes/base-release/code/_custom

dist/releases/1.0/changes/base-release/wksp_myproj

dist/releases/1.0/changes/base-release/wksp_myproj/ref_constraint

dist/releases/1.0/changes/base-release/wksp_myproj/ref_constraint/emp_mgr_fk.sql

dist/releases/1.0/changes/base-release/wksp_myproj/ref_constraint/emp_dept_fk.sql

dist/releases/1.0/changes/base-release/wksp_myproj/table

dist/releases/1.0/changes/base-release/wksp_myproj/table/emp.sql

dist/releases/1.0/changes/base-release/wksp_myproj/table/dept.sql

dist/releases/1.0/changes/base-release/wksp_myproj/index

dist/releases/1.0/changes/base-release/wksp_myproj/index/emp_2.sql

dist/releases/1.0/changes/base-release/wksp_myproj/index/emp_1.sql

dist/releases/1.0/changes/base-release/stage.changelog.xml

dist/releases/1.0/code

dist/releases/1.0/code/code.changelog.xml

dist/releases/1.0/code/wksp_myproj

dist/releases/1.0/code/wksp_myproj/view

dist/releases/1.0/code/wksp_myproj/view/emp_dept_v.sql


SQL> project gen-artifact

Your artifact has been generated myproj-1.0.zip

SQL> 


ディレクトリartifact以下に、デプロイ可能なアーティファクトとしてmyproj-1.0.zipが作成されました。

SQLclの接続先をローカルの環境に変更します。

sql wksp_myproj/[パスワード]@localhost/freepdb1

myproj % sql wksp_myproj/[パスワード]@localhost/freepdb1



SQLcl: 金 12月 06 16:32:50 2024のリリース24.3 Production


Copyright (c) 1982, 2024, Oracle.  All rights reserved.


接続先:

Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free

Version 23.5.0.24.07


SQL> 


アーティファクトmyproj-1.0.zipをローカル環境にデプロイします。

project deploy -file artifact/myproj-1.0.zip -verbose

SQL> project deploy -file artifact/myproj-1.0.zip -verbose

Check database connection...

Extract the file name: myproj-1.0

Artifact decompression in progress...

Artifact decompressed: /var/folders/fw/z20l7ys92zz_b2ryx2224y040000gn/T/bd56e2a6-6a92-444e-9ac2-c1a6e7031a9914375841397961038520

Starting the migration...

Running Changeset: base-release/wksp_myproj/table/dept.sql::b04d77535ce4d3477b4775c32ee177117eb2e849::WKSP_MYPROJ

Running Changeset: base-release/wksp_myproj/table/emp.sql::67ea942cdc254e93ba9cd9b1e4a0d38a2d586ab9::WKSP_MYPROJ

Running Changeset: base-release/wksp_myproj/ref_constraint/emp_dept_fk.sql::0ec3e2f9216a2bb4d9888bd93d5207de0255674d::WKSP_MYPROJ

Running Changeset: base-release/wksp_myproj/ref_constraint/emp_mgr_fk.sql::80728f400b510a76539aec3717998728dfb933af::WKSP_MYPROJ

Running Changeset: base-release/wksp_myproj/index/emp_1.sql::68cb87a9d748d75ad10c7877e960014abb5eb39e::WKSP_MYPROJ

Running Changeset: base-release/wksp_myproj/index/emp_2.sql::1bee5d3419726d3d1f7d8fbb044e53215266e578::WKSP_MYPROJ

Running Changeset: ../wksp_myproj/view/emp_dept_v.sql::e9c4fa13d41d45e366ca783319908d0ab8bbdacc::WKSP_MYPROJ

Running Changeset: releases/apex/f221/f221.xml::INSTALL_221::SQLCLWKSP_MYPROJ


PL/SQLプロシージャが正常に完了しました。


--application/set_environment

APPLICATION 221 - Demonstration - EMP / DEPT

--application/delete_application

--application/create_application

--application/user_interfaces

--workspace/credentials/アプリケーション221のプッシュ通知資格証明

--application/shared_components/navigation/lists/ナビゲーション・メニュー

--application/shared_components/navigation/lists/ナビゲーション・バー

--application/shared_components/navigation/lists/ページ・ナビゲーション

--application/shared_components/navigation/lists/アプリケーション構成

--application/shared_components/navigation/lists/ユーザー・インタフェース

--application/shared_components/navigation/lists/アクティビティ・レポート

--application/shared_components/navigation/lists/アクセス制御

--application/shared_components/navigation/lists/フィードバック

--application/shared_components/navigation/lists/ユーザー設定

--application/shared_components/navigation/listentry

--application/shared_components/files/icons_app_icon_32_png

--application/shared_components/files/icons_app_icon_144_rounded_png

--application/shared_components/files/icons_app_icon_192_png

--application/shared_components/files/icons_app_icon_256_rounded_png

--application/shared_components/files/icons_app_icon_512_png

--application/plugin_settings

--application/shared_components/security/authorizations/管理権限

--application/shared_components/security/authorizations/リーダー権限

--application/shared_components/security/authorizations/コントリビューション権限

--application/shared_components/security/app_access_control/管理者

--application/shared_components/security/app_access_control/コントリビュータ

--application/shared_components/security/app_access_control/リーダー

--application/shared_components/navigation/navigation_bar

--application/shared_components/logic/application_settings

--application/shared_components/navigation/tabs/standard

--application/shared_components/navigation/tabs/parent

--application/shared_components/user_interface/lovs/access_roles

--application/shared_components/user_interface/lovs/dept_dname

--application/shared_components/user_interface/lovs/desktop_theme_styles

--application/shared_components/user_interface/lovs/email_username_format

--application/shared_components/user_interface/lovs/emp_ename

--application/shared_components/user_interface/lovs/feedback_rating

--application/shared_components/user_interface/lovs/feedback_status

--application/shared_components/user_interface/lovs/timeframe_4_weeks

--application/shared_components/user_interface/lovs/user_theme_preference

--application/shared_components/user_interface/lovs/view_as_report_chart

--application/pages/page_groups

--application/shared_components/navigation/breadcrumbs/ブレッドクラム

--application/shared_components/navigation/breadcrumbentry

--application/shared_components/user_interface/templates/page/drawer

--application/shared_components/user_interface/templates/page/left_side_column

--application/shared_components/user_interface/templates/page/minimal_no_navigation

--application/shared_components/user_interface/templates/page/right_side_column

--application/shared_components/user_interface/templates/page/standard

--application/shared_components/user_interface/templates/page/wizard_modal_dialog

--application/shared_components/user_interface/templates/page/left_and_right_side_columns

--application/shared_components/user_interface/templates/page/login

--application/shared_components/user_interface/templates/page/master_detail

--application/shared_components/user_interface/templates/page/modal_dialog

--application/shared_components/user_interface/templates/button/icon

--application/shared_components/user_interface/templates/button/text

--application/shared_components/user_interface/templates/button/text_with_icon

--application/shared_components/user_interface/templates/region/alert

--application/shared_components/user_interface/templates/region/blank_with_attributes

--application/shared_components/user_interface/templates/region/blank_with_attributes_no_grid

--application/shared_components/user_interface/templates/region/carousel_container

--application/shared_components/user_interface/templates/region/image

--application/shared_components/user_interface/templates/region/inline_dialog

--application/shared_components/user_interface/templates/region/buttons_container

--application/shared_components/user_interface/templates/region/cards_container

--application/shared_components/user_interface/templates/region/content_block

--application/shared_components/user_interface/templates/region/collapsible

--application/shared_components/user_interface/templates/region/hero

--application/shared_components/user_interface/templates/region/inline_drawer

--application/shared_components/user_interface/templates/region/inline_popup

--application/shared_components/user_interface/templates/region/interactive_report

--application/shared_components/user_interface/templates/region/item_container

--application/shared_components/user_interface/templates/region/login

--application/shared_components/user_interface/templates/region/search_results_container

--application/shared_components/user_interface/templates/region/standard

--application/shared_components/user_interface/templates/region/tabs_container

--application/shared_components/user_interface/templates/region/title_bar

--application/shared_components/user_interface/templates/region/wizard_container

--application/shared_components/user_interface/templates/list/badge_list

--application/shared_components/user_interface/templates/list/cards

--application/shared_components/user_interface/templates/list/media_list

--application/shared_components/user_interface/templates/list/tabs

--application/shared_components/user_interface/templates/list/top_navigation_tabs

--application/shared_components/user_interface/templates/list/links_list

--application/shared_components/user_interface/templates/list/menu_bar

--application/shared_components/user_interface/templates/list/top_navigation_mega_menu

--application/shared_components/user_interface/templates/list/wizard_progress

--application/shared_components/user_interface/templates/list/menu_popup

--application/shared_components/user_interface/templates/list/navigation_bar

--application/shared_components/user_interface/templates/list/side_navigation_menu

--application/shared_components/user_interface/templates/list/top_navigation_menu

--application/shared_components/user_interface/templates/report/alerts

--application/shared_components/user_interface/templates/report/badge_list

--application/shared_components/user_interface/templates/report/cards

--application/shared_components/user_interface/templates/report/search_results

--application/shared_components/user_interface/templates/report/value_attribute_pairs_column

--application/shared_components/user_interface/templates/report/value_attribute_pairs_row

--application/shared_components/user_interface/templates/report/comments

--application/shared_components/user_interface/templates/report/contextual_info

--application/shared_components/user_interface/templates/report/standard

--application/shared_components/user_interface/templates/report/content_row

--application/shared_components/user_interface/templates/report/timeline

--application/shared_components/user_interface/templates/report/media_list

--application/shared_components/user_interface/templates/label/hidden

--application/shared_components/user_interface/templates/label/optional

--application/shared_components/user_interface/templates/label/optional_above

--application/shared_components/user_interface/templates/label/optional_floating

--application/shared_components/user_interface/templates/label/required

--application/shared_components/user_interface/templates/label/required_above

--application/shared_components/user_interface/templates/label/required_floating

--application/shared_components/user_interface/templates/breadcrumb/breadcrumb

--application/shared_components/user_interface/templates/popuplov

--application/shared_components/user_interface/templates/calendar/calendar

--application/shared_components/user_interface/themes

--application/shared_components/user_interface/theme_style

--application/shared_components/user_interface/theme_files

--application/shared_components/user_interface/template_opt_groups

--application/shared_components/user_interface/template_options

--application/shared_components/globalization/language

--application/shared_components/logic/build_options

--application/shared_components/globalization/messages

--application/shared_components/globalization/dyntranslations

--application/shared_components/security/authentications/oracle_apexアカウント

--application/shared_components/plugins/template_component/theme_42_avatar

--application/shared_components/plugins/template_component/theme_42_badge

--application/shared_components/plugins/template_component/theme_42_button

--application/shared_components/plugins/template_component/theme_42_comments

--application/shared_components/plugins/template_component/theme_42_media_list

--application/shared_components/plugins/template_component/theme_42_timeline

--application/shared_components/plugins/template_component/theme_42_content_row

--application/user_interfaces/combined_files

--application/pages/page_00000

--application/pages/page_00001

--application/pages/page_00002

--application/pages/page_00003

--application/pages/page_00004

--application/pages/page_00005

--application/pages/page_00006

--application/pages/page_09999

--application/pages/page_10000

--application/pages/page_10010

--application/pages/page_10020

--application/pages/page_10030

--application/pages/page_10031

--application/pages/page_10032

--application/pages/page_10033

--application/pages/page_10034

--application/pages/page_10035

--application/pages/page_10036

--application/pages/page_10040

--application/pages/page_10041

--application/pages/page_10042

--application/pages/page_10043

--application/pages/page_10044

--application/pages/page_10050

--application/pages/page_10051

--application/pages/page_10053

--application/pages/page_10054

--application/pages/page_10060

--application/pages/page_10061

--application/pages/page_20000

--application/pages/page_20010

--application/end_environment

...done


Liquibase: Update has been successful. Rows affected: 8

Installing/updating schemas

--Starting Liquibase at 2024-12-06T16:36:53.476125 (version 4.25.0.305.0400 #0 built at 2024-10-31 21:25+0000)


PL/SQLプロシージャが正常に完了しました。


--application/set_environment

APPLICATION 221 - Demonstration - EMP / DEPT

--application/delete_application

--application/create_application

--application/user_interfaces

--workspace/credentials/アプリケーション221のプッシュ通知資格証明

--application/shared_components/navigation/lists/ナビゲーション・メニュー

--application/shared_components/navigation/lists/ナビゲーション・バー

--application/shared_components/navigation/lists/ページ・ナビゲーション

--application/shared_components/navigation/lists/アプリケーション構成

--application/shared_components/navigation/lists/ユーザー・インタフェース

--application/shared_components/navigation/lists/アクティビティ・レポート

--application/shared_components/navigation/lists/アクセス制御

--application/shared_components/navigation/lists/フィードバック

--application/shared_components/navigation/lists/ユーザー設定

--application/shared_components/navigation/listentry

--application/shared_components/files/icons_app_icon_32_png

--application/shared_components/files/icons_app_icon_144_rounded_png

--application/shared_components/files/icons_app_icon_192_png

--application/shared_components/files/icons_app_icon_256_rounded_png

--application/shared_components/files/icons_app_icon_512_png

--application/plugin_settings

--application/shared_components/security/authorizations/管理権限

--application/shared_components/security/authorizations/リーダー権限

--application/shared_components/security/authorizations/コントリビューション権限

--application/shared_components/security/app_access_control/管理者

--application/shared_components/security/app_access_control/コントリビュータ

--application/shared_components/security/app_access_control/リーダー

--application/shared_components/navigation/navigation_bar

--application/shared_components/logic/application_settings

--application/shared_components/navigation/tabs/standard

--application/shared_components/navigation/tabs/parent

--application/shared_components/user_interface/lovs/access_roles

--application/shared_components/user_interface/lovs/dept_dname

--application/shared_components/user_interface/lovs/desktop_theme_styles

--application/shared_components/user_interface/lovs/email_username_format

--application/shared_components/user_interface/lovs/emp_ename

--application/shared_components/user_interface/lovs/feedback_rating

--application/shared_components/user_interface/lovs/feedback_status

--application/shared_components/user_interface/lovs/timeframe_4_weeks

--application/shared_components/user_interface/lovs/user_theme_preference

--application/shared_components/user_interface/lovs/view_as_report_chart

--application/pages/page_groups

--application/shared_components/navigation/breadcrumbs/ブレッドクラム

--application/shared_components/navigation/breadcrumbentry

--application/shared_components/user_interface/templates/page/drawer

--application/shared_components/user_interface/templates/page/left_side_column

--application/shared_components/user_interface/templates/page/minimal_no_navigation

--application/shared_components/user_interface/templates/page/right_side_column

--application/shared_components/user_interface/templates/page/standard

--application/shared_components/user_interface/templates/page/wizard_modal_dialog

--application/shared_components/user_interface/templates/page/left_and_right_side_columns

--application/shared_components/user_interface/templates/page/login

--application/shared_components/user_interface/templates/page/master_detail

--application/shared_components/user_interface/templates/page/modal_dialog

--application/shared_components/user_interface/templates/button/icon

--application/shared_components/user_interface/templates/button/text

--application/shared_components/user_interface/templates/button/text_with_icon

--application/shared_components/user_interface/templates/region/alert

--application/shared_components/user_interface/templates/region/blank_with_attributes

--application/shared_components/user_interface/templates/region/blank_with_attributes_no_grid

--application/shared_components/user_interface/templates/region/carousel_container

--application/shared_components/user_interface/templates/region/image

--application/shared_components/user_interface/templates/region/inline_dialog

--application/shared_components/user_interface/templates/region/buttons_container

--application/shared_components/user_interface/templates/region/cards_container

--application/shared_components/user_interface/templates/region/content_block

--application/shared_components/user_interface/templates/region/collapsible

--application/shared_components/user_interface/templates/region/hero

--application/shared_components/user_interface/templates/region/inline_drawer

--application/shared_components/user_interface/templates/region/inline_popup

--application/shared_components/user_interface/templates/region/interactive_report

--application/shared_components/user_interface/templates/region/item_container

--application/shared_components/user_interface/templates/region/login

--application/shared_components/user_interface/templates/region/search_results_container

--application/shared_components/user_interface/templates/region/standard

--application/shared_components/user_interface/templates/region/tabs_container

--application/shared_components/user_interface/templates/region/title_bar

--application/shared_components/user_interface/templates/region/wizard_container

--application/shared_components/user_interface/templates/list/badge_list

--application/shared_components/user_interface/templates/list/cards

--application/shared_components/user_interface/templates/list/media_list

--application/shared_components/user_interface/templates/list/tabs

--application/shared_components/user_interface/templates/list/top_navigation_tabs

--application/shared_components/user_interface/templates/list/links_list

--application/shared_components/user_interface/templates/list/menu_bar

--application/shared_components/user_interface/templates/list/top_navigation_mega_menu

--application/shared_components/user_interface/templates/list/wizard_progress

--application/shared_components/user_interface/templates/list/menu_popup

--application/shared_components/user_interface/templates/list/navigation_bar

--application/shared_components/user_interface/templates/list/side_navigation_menu

--application/shared_components/user_interface/templates/list/top_navigation_menu

--application/shared_components/user_interface/templates/report/alerts

--application/shared_components/user_interface/templates/report/badge_list

--application/shared_components/user_interface/templates/report/cards

--application/shared_components/user_interface/templates/report/search_results

--application/shared_components/user_interface/templates/report/value_attribute_pairs_column

--application/shared_components/user_interface/templates/report/value_attribute_pairs_row

--application/shared_components/user_interface/templates/report/comments

--application/shared_components/user_interface/templates/report/contextual_info

--application/shared_components/user_interface/templates/report/standard

--application/shared_components/user_interface/templates/report/content_row

--application/shared_components/user_interface/templates/report/timeline

--application/shared_components/user_interface/templates/report/media_list

--application/shared_components/user_interface/templates/label/hidden

--application/shared_components/user_interface/templates/label/optional

--application/shared_components/user_interface/templates/label/optional_above

--application/shared_components/user_interface/templates/label/optional_floating

--application/shared_components/user_interface/templates/label/required

--application/shared_components/user_interface/templates/label/required_above

--application/shared_components/user_interface/templates/label/required_floating

--application/shared_components/user_interface/templates/breadcrumb/breadcrumb

--application/shared_components/user_interface/templates/popuplov

--application/shared_components/user_interface/templates/calendar/calendar

--application/shared_components/user_interface/themes

--application/shared_components/user_interface/theme_style

--application/shared_components/user_interface/theme_files

--application/shared_components/user_interface/template_opt_groups

--application/shared_components/user_interface/template_options

--application/shared_components/globalization/language

--application/shared_components/logic/build_options

--application/shared_components/globalization/messages

--application/shared_components/globalization/dyntranslations

--application/shared_components/security/authentications/oracle_apexアカウント

--application/shared_components/plugins/template_component/theme_42_avatar

--application/shared_components/plugins/template_component/theme_42_badge

--application/shared_components/plugins/template_component/theme_42_button

--application/shared_components/plugins/template_component/theme_42_comments

--application/shared_components/plugins/template_component/theme_42_media_list

--application/shared_components/plugins/template_component/theme_42_timeline

--application/shared_components/plugins/template_component/theme_42_content_row

--application/user_interfaces/combined_files

--application/pages/page_00000

--application/pages/page_00001

--application/pages/page_00002

--application/pages/page_00003

--application/pages/page_00004

--application/pages/page_00005

--application/pages/page_00006

--application/pages/page_09999

--application/pages/page_10000

--application/pages/page_10010

--application/pages/page_10020

--application/pages/page_10030

--application/pages/page_10031

--application/pages/page_10032

--application/pages/page_10033

--application/pages/page_10034

--application/pages/page_10035

--application/pages/page_10036

--application/pages/page_10040

--application/pages/page_10041

--application/pages/page_10042

--application/pages/page_10043

--application/pages/page_10044

--application/pages/page_10050

--application/pages/page_10051

--application/pages/page_10053

--application/pages/page_10054

--application/pages/page_10060

--application/pages/page_10061

--application/pages/page_20000

--application/pages/page_20010

--application/end_environment

...done



UPDATE SUMMARY

Run:                          8

Previously run:               0

Filtered out:                 0

-------------------------------

Total change sets:            8



Produced logfile: sqlcl-lb-1733470613402.log


操作が正常に完了しました。



Migration has been completed

Removing the decompressed artifact: /var/folders/fw/z20l7ys92zz_b2ryx2224y040000gn/T/bd56e2a6-6a92-444e-9ac2-c1a6e7031a9914375841397961038520...

SQL> 


以上でSQLclのprojectコマンドを使った環境のコピーは完了です。

APEXのワークスペースにサインインして結果を確認します。

アプリケーション・ビルダーからは、アプリケーションDemonstration - EMP / DEPTが作成されていることが確認できます。


オブジェクト・ブラウザからは表EMPDEPTおよびビューEMP_DEPT_Vが作成されていることが確認できます。


しかし、表EMPおよびDEPTの中身は空です。(カスタム・コードを追加しない限り)SQLclのprojectは、データの移行は行いません。


REST対応SQLを使ったデータのコピー - ローカル環境



Autonomous Databaseのデータをローカル環境にコピーするために、REST対応SQLを呼び出します。すでにAutonomous Database側の準備はできています。

最初にREST対応SQLを認証するためのWeb資格証明を作成します。

ワークスペース・ユーティリティWeb資格証明を開きます。


作成をクリックします。


Web資格証明は基本認証OAuth2クライアント資格証明のどちらかで作成します。

作成するWeb資格証明の名前Cred MYPROJとします。静的IDは後ほどデータのコピーを実行する際に参照するため、あらかじめCRED_MYPROJと指定しておきます。

認証タイプとして基本認証を選択したときは、クライアントIDまたはユーザー名にはスキーマ名のWKSP_MYPROJクライアント・シークレットまたはパスワードには、WKSP_MYPROJのパスワードを指定します。


証明タイプとしてOAuth2クライアント資格証明を選択したときは、クライアントIDまたはユーザー名にはビューUSER_ORDS_CLIENTSの列CLIENT_IDの値、クライアント・シークレットまたはパスワードには、ビューUSER_ORDS_CLIENTSの列CLIENT_SECRETの値を指定します。

以上で作成をクリックします。


Web資格証明Cred MYPROJが作成されました。


続けてREST対応SQLサービスを作成します。

ワークスペース・ユーティリティに含まれるREST対応SQLサービスを開きます。


REST対応SQLサービスを作成します。


REST対応SQLサービスの名前とエンドポイントURLを入力します。今回は名前MYPROJ on ADBとしました。エンドポイントURLは以下の形式のURLです。

https://[ホスト名]/ords/myproj

へ進みます。


資格証明として先ほど作成したCred MYPROJを選択します。

以上で作成をクリックします。


成功と表示されたらREST対応SQLサービスが作成できています。

閉じるをクリックします。


REST対応SQLサービスは、作成時に静的IDを指定する項目が無く、また、自動的に割り当てられる静的IDはなぜか小文字です。扱いにくいため、静的IDを変更します。

MYPROJ on ADBの編集画面を開きます。


静的IDMYPROJ_ON_ADBに変更し、変更の適用をクリックします。


以上でREST対応SQLサービスの準備ができました。

作成されたAPEXアプリケーションDemonstration - EMP / DEPTはAPEXの標準機能であるアクセス制御が含まれています。APEXアプリケーションのエクスポートにはセキュリティ上の脆弱性を排除するため、ユーザー・ロール割当てが含まれません。

アプリケーションの共有コンポーネントアプリケーション・アクセス制御を開き、ユーザー・ロール割当てを追加します。


ユーザー・ロール割当ての追加をクリックします。


ユーザー名MYPROJADMを入力し、アプリケーション・ロール管理者をチェックします。

割当ての作成をクリックします。


ユーザー・ロール割当てが追加されました。


アプリケーションを実行し、ユーザーMYPROJADMでサインインします。

REST対応SQLを使ったデータ・コピーを実行する際にアプリケーションIDが必要になるため、あらかじめ確認しておきます。以下のスクリーンショットからは、221がアプリケーションIDであることが分かります。

アプリケーションを実行します。


ユーザーMYPROJADMでサインインします。


アプリケーションのホーム・ページが開きます。Emplyeesを開いてみます。


表EMPにデータが含まれていないため、レポートにはデータが見つかりませんと表示されます。


これからデータのコピーを実行します。REST対応SQLを呼び出してデータをコピーする機能を実装したパッケージをUTL_REST_ENABLED_SQL_COPYとして作成しました。パッケージ定義と本体のコードを本記事の末尾に添付しています。

このパッケージでコピーできるデータ型はVARCHAR2、NUMBER、DATE、TIMESTAMP、TIMESTAMP WITH TIME ZONE、TIMESTAMP WITH LOCAL TIME ZONE、CLOB、INTERVAL DAY TO SECOND、INTERVAL YEAR TO MONTHに限り、それ以外のBLOB、ANYDATA、VECTOR、JSON、SDO_GEOMETRYなどには対応していません。

ローカル環境にデータベース・ユーザーWKSP_MYPROJで接続します。

sql wksp_myproj/My*********ac@localhost/freepdb1

パッケージUTL_REST_ENBLED_SQL_COPYを作成します。

@utl_rest_enabled_sql_copy.sql
@utl_rest_enabled_sql_copy.pkb


SQL> @utl_rest_enabled_sql_copy.sql


Package UTL_REST_ENABLED_SQL_COPYがコンパイルされました


SQL> @utl_rest_enabled_sql_copy.pkb


Package Body UTL_REST_ENABLED_SQL_COPYがコンパイルされました


SQL> 


DESCコマンドを実行し、実装されているファンクションまたはプロシージャを確認します。

desc utl_rest_enabled_sql_copy

SQL> desc utl_rest_enabled_sql_copy


FUNCTION COPY_TABLE_FROM_LOCAL_TO_REMOTE RETURNS NUMBER

  Argument Name             Type                 In/Out Default?

  ------------------------- -------------------- ------ --------

  P_SERVER_STATIC_ID        VARCHAR2             IN      

  P_TABLE_NAME              VARCHAR2             IN      

  P_COMMIT_INTERVAL         BINARY_INTEGER       IN     Y

  P_CONTINUE_ON_ERROR       BOOLEAN              IN     Y


FUNCTION COPY_TABLE_FROM_LOCAL_TO_REMOTE_S RETURNS NUMBER

  Argument Name             Type                 In/Out Default?

  ------------------------- -------------------- ------ --------

  P_APP_ID                  NUMBER               IN      

  P_PAGE_ID                 NUMBER               IN     Y

  P_USERNAME                VARCHAR2             IN      

  P_SERVER_STATIC_ID        VARCHAR2             IN      

  P_TABLE_NAME              VARCHAR2             IN      

  P_COMMIT_INTERVAL         BINARY_INTEGER       IN     Y

  P_CONTINUE_ON_ERROR       BOOLEAN              IN     Y

  P_DEBUG_LEVEL             BINARY_INTEGER       IN     Y


FUNCTION COPY_TABLE_FROM_REMOTE_TO_LOCAL RETURNS NUMBER

  Argument Name             Type                 In/Out Default?

  ------------------------- -------------------- ------ --------

  P_SERVER_STATIC_ID        VARCHAR2             IN      

  P_TABLE_NAME              VARCHAR2             IN      

  P_COMMIT_INTERVAL         BINARY_INTEGER       IN     Y


FUNCTION COPY_TABLE_FROM_REMOTE_TO_LOCAL_S RETURNS NUMBER

  Argument Name             Type                 In/Out Default?

  ------------------------- -------------------- ------ --------

  P_APP_ID                  NUMBER               IN      

  P_PAGE_ID                 NUMBER               IN     Y

  P_USERNAME                VARCHAR2             IN      

  P_SERVER_STATIC_ID        VARCHAR2             IN      

  P_TABLE_NAME              VARCHAR2             IN      

  P_COMMIT_INTERVAL         BINARY_INTEGER       IN     Y

  P_DEBUG_LEVEL             BINARY_INTEGER       IN     Y



SQL> 


今回はリモートのAutonomous Databaseからローカルの環境にコピーするため、プロシージャCOPY_TABLE_FROM_REMOTE_TO_LOCAL_Sを呼び出します。

最初に表DEPTのデータをコピーします。表EMPのデータは表DEPTのDEPTNOを参照しているため、EMPよりも先にDEPTにデータがコピーされている必要があります。
variable rows number
begin
    :rows := utl_rest_enabled_sql_copy.copy_table_from_remote_to_local_s(221,1,'MYPROJADM','MYPROJ_ON_ADB','DEPT');
end;
/
print :rows
select * from dept;
実行するとローカルの表DEPTにデータがコピーされます。

SQL> variable rows number;

SQL> begin

  2  :rows := utl_rest_enabled_sql_copy.copy_table_from_remote_to_local_s(221,1,'MYPROJADM','MYPROJ_ON_ADB','DEPT');

  3  end;

  4* /


PL/SQLプロシージャが正常に完了しました。


SQL> print :rows


      ROWS

----------

         4


SQL> select * from dept;


   DEPTNO DNAME         LOC         

_________ _____________ ___________ 

       10 ACCOUNTING    NEW YORK    

       20 RESEARCH      DALLAS      

       30 SALES         CHICAGO     

       40 OPERATIONS    BOSTON      


SQL>


続いて表EMPのデータをコピーします。
begin
    :rows := utl_rest_enabled_sql_copy.copy_table_from_remote_to_local_s(221,1,'MYPROJADM','MYPROJ_ON_ADB','EMP');
end;
/
print :rows
select * from emp;
表EMPにデータがコピーされます。

SQL> begin

  2  :rows := utl_rest_enabled_sql_copy.copy_table_from_remote_to_local_s(221,1,'MYPROJADM','MYPROJ_ON_ADB','EMP');

  3  end;

  4* /


PL/SQLプロシージャが正常に完了しました。


SQL> print :rows


      ROWS

----------

        14


SQL> select * from emp;


   EMPNO ENAME     JOB              MGR HIREDATE        SAL    COMM    DEPTNO 

________ _________ ____________ _______ ___________ _______ _______ _________ 

    7839 KING      PRESIDENT            81-11-17       5000                10 

    7698 BLAKE     MANAGER         7839 81-05-01       2850                30 

    7782 CLARK     MANAGER         7839 81-06-09       2450                10 

    7566 JONES     MANAGER         7839 81-04-02       2975                20 

    7788 SCOTT     ANALYST         7566 82-12-09       3000                20 

    7902 FORD      ANALYST         7566 81-12-03       3000                20 

    7369 SMITH     CLERK           7902 80-12-17        800                20 

    7499 ALLEN     SALESMAN        7698 81-02-20       1600     300        30 

    7521 WARD      SALESMAN        7698 81-02-22       1250     500        30 

    7654 MARTIN    SALESMAN        7698 81-09-28       1250    1400        30 

    7844 TURNER    SALESMAN        7698 81-09-08       1500       0        30 

    7876 ADAMS     CLERK           7788 83-01-12       1100                20 

    7900 JAMES     CLERK           7698 81-12-03        950                30 

    7934 MILLER    CLERK           7782 82-01-23       1300                10 


14行が選択されました。 


SQL> 


先ほどサインインしたAPEXアプリケーションに戻ると、レポートに従業員の一覧が表示されてることが確認できます。


以上でAutonomous Databaseの環境をローカルのAPEX環境にコピーする作業が完了しました。

SQLclには以前よりLiquibaseが組み込まれていて、スキーマの移行はそれを使えば可能でした。しかし、Liquibaseを使いこなすのは相当ハードルが高かったと思います。SQLclのprojectも内部ではLiquibaseを使っていますが、かなり取り組みやすくなりました。

今回の記事は以上になります。

Oracle APEXのアプリケーション開発の参考になれば幸いです。