OracleAPEX上でバックアップを作成しオブジェクトストレージに出力する

# 初めに
OracleAPEXでは自動バックアップ機能がありますが、何かしらのエラーで復元出来ないことがあります。そのため別個でファイルを保存する方法を探した所、オブジェクトストレージにアプリケーションファイルを保存できる方法を見つけたのでご紹介させて頂きます。

# 準備
まずコード内で使用するオブジェクトストレージを操作できるPL/SQLパッケージの権限を付与する必要があります。

OCI上からAPEXが紐づいているAutonomousDBのページに行き、「データベース・アクション」を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2752288/29204465-dce2-ff48-b4d7-f7bebc082f6e.png)

「データベース・ユーザー」を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2752288/2f5f328b-b09e-0293-89fa-6942b11c139d.png)

処理を実行したいワークスペース・ユーザーの「編集」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2752288/befe80ab-ba97-d061-f46e-a13d7f6b4911.png)

「付与されたロール」を選択し、「DWROLE」の「付与済」と「管理」を選択。
「変更の適用」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2752288/ff1f8743-c83a-069c-35d8-136789768caa.png)

再びOCI上からAPEXが紐づいているAutonomousDBのページに行き、「データベース・アクション」を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2752288/29204465-dce2-ff48-b4d7-f7bebc082f6e.png)

「SQL」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2752288/c291523c-c33f-ae28-6153-7e55d07742e3.png)

以下コードを実行して権限を付与。
```
grant execute on DBMS_CLOUD_OCI_OBS_OBJECT_STORAGE to ワークスペース・ユーザー名;
grant execute on DBMS_CLOUD_OCI_OBS_OBJECT_STORAGE_PUT_OBJECT_RESPONSE_T to ワークスペース・ユーザー名;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2752288/d38ecb63-88a3-51c3-7a56-2850f1f1b86b.png)

OCI側で実行権限を持つユーザーを作成します。
メニューから「アイデンティティとセキュリティ」、ドメインを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2752288/4e024e70-7a8d-c5c1-067f-06f758bf37a2.png)

ユーザーを作成し、この際にグループを「OCI_Administrators」にします。
※オブジェクトストレージにアクセス制限したい場合は専用のグループを作成して割り当てて下さい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2752288/fd1ab899-64c6-dfb2-cb82-fd7cedba1f3e.png)

作成したユーザーのAPIキーを発行します。
秘密キーはダウンロードしておき、作成後の構成ファイルのプレビューをコピーして保存。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2752288/7a4f4e79-5cf8-996f-f0ec-3b337391b3f7.png)

APEXのSQL Workshopから以下のSQLを実行しクレデンシャルを作成。
```
BEGIN
DBMS_CLOUD.CREATE_CREDENTIAL (
credential_name => 'クレデンシャル名',
user_ocid => '作成したユーザーのocid',
tenancy_ocid => 'テナントID',
private_key => 'ダウンロードした秘密キーの内容',
fingerprint => '作成したフィンガープリント');
END;
/
```

# 実行
APEXのSQL Workshopから以下のSQLを実行します。

```
declare
    blobData   BLOB;
    intApplicationId INTEGER := '保存したいアプリケーションID';
    response   DBMS_CLOUD_OCI_OBS_OBJECT_STORAGE_PUT_OBJECT_RESPONSE_T;
    intDestOffset   INTEGER := 1;
    intSrcOffset     INTEGER := 1;
    intLangContext    INTEGER := 0;
    intWarning INTEGER := 0;
    apexFiles APEX_T_EXPORT_FILES;
    strUploadPath VARCHAR2(25) := 'オブジェクトストレージ内で保存したいパス';
begin
--APEXアプリケーションからエクスポートされたSQLファイルを取得
apexFiles := APEX_EXPORT.GET_APPLICATION(
    p_application_id => intApplicationId,
    p_split => FALSE,
    p_with_date => FALSE,
    p_with_ir_public_reports  => TRUE,
    p_with_ir_private_reports  => TRUE,
    p_with_ir_notifications  => TRUE,
    p_with_translations => TRUE,
    p_with_pkg_app_mapping  => TRUE,
    p_with_original_ids => TRUE,
    p_with_no_subscriptions => TRUE,
    p_with_comments => TRUE,
    p_with_supporting_objects   => 'Y',
    p_with_acl_assignments=> TRUE
 );

--BLOBオブジェクトを作成する領域を確保
DBMS_LOB.CREATETEMPORARY(blobData,FALSE,DBMS_LOB.SESSION);

--BLOBオブジェクトにAPEXアプリケーションの文字列を書き込む
DBMS_LOB.CONVERTTOBLOB(blobData, apexFiles(1).CONTENTS, DBMS_LOB.LOBMAXSIZE, intDestOffset, intSrcOffset, DBMS_LOB.DEFAULT_CSID, intLangContext, intWarning);

--オブジェクトストレージにBLOBファイルをアップロード
response := DBMS_CLOUD_OCI_OBS_OBJECT_STORAGE.PUT_OBJECT(
                namespace_name => 'オブジェクトストレージのネームスペース',
                bucket_name => 'オブジェクトストレージのバケット名',
                object_name => strUploadPath || TO_CHAR(SYSDATE,'YYYYMMDD') || '_' || apexFiles(1).NAME,
                put_object_body => blobData,
                credential_name => 'クレデンシャル名',
                region => 'オブジェクトストレージのリージョン名',
                content_type  => 'application/octet-stream');
end;
/
```

無事オブジェクトストレージにアプリケーションファイル(SQL)が保存できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2752288/701794b6-1052-0431-d664-05dd3033cb05.png)

アプリケーション内でプロシージャとして実行する、自動化で日次バックアップを行うことも可能です。


以上となります。
見て下さりありがとうございました。