オブジェクト・ストレージからOracle DB 19c/21cにデータを導入する

本ブログは、[オラクル・クラウドの個人ブログ](https://qiita.com/letian/items/10152a4fec813c1b7d98)の1つです。

# 初めに
オブジェクト・ストレージに保存されるデータファイルをOracle DBに導入したいで、ODI (Oracle Data Integrator)以外に、何か方法がありますか？

答えは<font color="blue">YES</font>で、<font color="blue">DBMS_CLOUD</font>というパッケージを利用すれば可能です。

- Autonomous DBの場合、DBMS_CLOUDは既に<strong>実装済</strong>で、そのままを利用すれば、簡単にOCIオブジェクト・ストレージに保存されるファイルが取り込めます。
- Oracle DB(On-P/Cloud両方)の場合、DBMS_CLOUDが実装されていませんけど、<font color="blue">手動のインストールは可能</font>です。
※、オラクルが、下記のMOSドキュメントを提供しています。（アカウントは必要）
[How To Setup And Use DBMS_CLOUD Package (Doc ID 2748362.1)](https://support.oracle.com/epmos/faces/DocumentDisplay?_afrLoop=273654378015774&id=2748362.1)

OCIオブジェクト・ストレージだけではなく、<font color="blue">AWS S3, Azure Blobストレージ</font>に保存されても導入できます。今回は、OCIオブジェクト・ストレージにある<font color="blue">CSVとDUMP</font>ファイルをOracle Base DBに導入する方法をご紹介します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/03597d11-97eb-e5b4-5a4d-869c36171db8.png", width="500">

本記事は、以下の３部分の内容を含めています。
 - Oracle DBにDBMS_CLOUDをインストールする方法。
 - DBMS_CLOUDで、OCIオブジェクト・ストレージから<strong>CSV</strong>ファイルをOracle DBへロードする方法。
 - DBMS_CLOUDで、OCIオブジェクト・ストレージから<strong>DUMP</strong>ファイルを<strong>ローカルにコピー</strong>してから、Oracle DBへインポートする方法。


__利用条件__
 Oracle DB 19cのバージョンは、<font color="blue">19.9以上</font>です。 Oracle DB 21cのバージョンは、<font color="blue">21.3以上</font>です。
 (On-P/Cloud両方に、適用します。)

__実施ステップ__

* [STEP 1 - 事前準備](#step-1---事前準備)
* [STEP 2 - DBMS_CLOUDのインストール](#step-2---dbms_cloudのインストール)
* [STEP 3 - Walletの作成](#step-3---walletの作成)
* [STEP 4 - Wallet場所の設定](#step-4---wallet場所の設定)
* [STEP 5 - ACEs(Access Control Entries)の設定](#step-5---acesaccess-control-entriesの設定)
* [STEP 6 - DBMS_CLOUDの設定を検証](#step-6---dbms_cloudの設定を検証)
* [STEP 7 - ユーザ・ロールへの権限付与](#step-7---ユーザロールへの権限付与)
* [STEP 8 - ユーザ・ロールのため、ACEsを設定](#step-8---ユーザロールのためacesを設定)
* [STEP 9 - クレデンシャルの作成と検証](#step-9---クレデンシャルの作成と検証)
* [STEP10 - オブジェクト・ストレージからCSVファイルをDBにコピー](#step10---オブジェクトストレージからcsvファイルをdbにコピー)
* [STEP11 - オブジェクト・ストレージからDUMPファイルをDBにインポート](#step11---オブジェクトストレージからdumpファイルをdbにインポート)

# STEP 1 - 事前準備
__実施環境__
この例は、OCI上のDB System(VM)を利用します。
リージョン：Tokyo
DBバージョン：19.10 Standard Edition

OCIユーザの<font color="blue">認証トークン</font>(Auth Token)を事前に用意してください。作成方法は、[ドキュメント](https://docs.oracle.com/ja-jp/iaas/Content/Registry/Tasks/registrygettingauthtoken.htm)をご参考ください。ここで省略します。

__関連スクリプトと証明書__
MOSドキュメントに、実施用<font color="blue">SQLスクリプト</font>が用意されています。コピーペーストで、ファイルを作成しておいてください。
表内の各SQLファイルの内容は、MOSドキュメントと同じです。
（MOSドキュメントに、<font color="blue">dbms_cloud_install.sqlとdcs_aces.sql</font>の２個だけ、名前があります。ほかのは自分より名前を付けました。）

|No.|名前&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|  目的    |修正箇所|コメント|
|:--:|:------|:--------|:-----------|:-----------|
|1|[dbms_cloud_install.sql](https://github.com/liu-wei1/dbms_cloud/blob/main/dbms_cloud_install.sql)| DBMS_CLOUDのインストール     |なし||
|2|[dbc_aces.sql](https://github.com/liu-wei1/dbms_cloud/blob/main/dbc_aces.sql)| Access Control Entries (ACEs)の設定     |define sslwalletdir=\<Set SSL Wallet Directory>||
|3|[verify_aces.sql](https://github.com/liu-wei1/dbms_cloud/blob/main/verify_aces.sql)| ACEs設定後の確認     |1. define sslwalletdir=\<Set SSL Wallet Directory><br>2. define sslwalletpwd=\<Set SSL Wallet password><br>3. GET_PAGE(\<Object Storage URL>);|3.リージョンキーを置き換え:<br>ap-tokyo-1 (東京リージョン)|
|4|[grant_user.sql](https://github.com/liu-wei1/dbms_cloud/blob/main/grant_user.sql)|指定ユーザに権限を付与      |define username='SCOTT'|4と5は、どちらを選ぶ|
|5|[grant_role.sql](https://github.com/liu-wei1/dbms_cloud/blob/main/grant_role.sql)|指定ユーザにロールを付与     |1. define userrole='CLOUD_USER'<br>2. define username='SCOTT'||
|6|[config_aces_for_user.sql](https://github.com/liu-wei1/dbms_cloud/blob/main/config_aces_for_user.sql)|指定ユーザにACEsを設定      |1. define clouduser=SCOTT<br>2. define sslwalletdir=\<Set SSL Wallet Directory>|ユーザに権限を付与(上記の4)した場合、これを利用する|
|7|[config_aces_for_role.sql](https://github.com/liu-wei1/dbms_cloud/blob/main/config_aces_for_role.sql)|指定ロールにACEsを設定      |1. define cloudrole=CLOUD_USER<br>2. define sslwalletdir=\<Set SSL Wallet Directory>|ロールに権限を付与(上記の5)した場合、これを利用する|
|8|[validate_user_config.sql](https://github.com/liu-wei1/dbms_cloud/blob/main/validate_user_config.sql)|設定した権限を検証      |1. define clouduser=SCOTT<br>2. define sslwalletdir=\<Set SSL Wallet Directory><br>3. define sslwalletpwd=\<Set SSL Wallet password><br>4. GET_PAGE(\<Object Storage URL>);|4. リージョンキーを置き換え:<br>ap-tokyo-1 (東京リージョン)|
|9|[dbc_certs.tar](https://objectstorage.us-phoenix-1.oraclecloud.com/p/QsLX1mx9A-vnjjohcC7TIK6aTDFXVKr0Uogc2DAN-Rd7j6AagsmMaQ3D3Ti4a9yU/n/adwcdemo/b/CERTS/o/dbc_certs.tar) |証明書      |なし|既に証明書を所有している場合、これは不要）|


__関連ファイルの保存先__

|No.|パス|  ファイル名    |コメント|
|:--:|:------|:--------|:-----------|
|1|/home/oracle/<font color="blue">dbc</font> (作成要)| 上記8個のSQLファイル     |SQLスクリプト格納先|
|2|/home/oracle/<font color="blue">cert</font> (作成要)| dbc_certs.tar      |証明書格納先|
|3|/opt/oracle/dcs/commonstore/wallets/<font color="blue">ssl</font> (作成要)|       |Wallet格納先|
|4|$ORACLE_HOME/network/admin|sqlnet.ora      ||

※MOSドキュメントに、SQLスクリプトと証明書が、同じディレクトリ(/home/oracle/dbc)の下に保存されますが、この例で分けて保存します。

# STEP 2 - DBMS_CLOUDのインストール

SYSユーザのパスワードを用意してから、以下のコマンドを実施します。

<strong>コマンド</strong>：
`$ORACLE_HOME/perl/bin/perl` `$ORACLE_HOME/rdbms/admin/catcon.pl` -u <font color="blue">sys/\<your_sys_password></font> --force_pdb_mode 'READ WRITE' -b dbms_cloud_install -d /home/oracle/dbc -l /home/oracle/dbc <font color="blue">dbms_cloud_install.sql</font>

```
[oracle@db19c dbc]$ pwd
/home/oracle/dbc
[oracle@db19c dbc]$ ll
total 32
-rwxr-xr-x 1 oracle oinstall 1639 May 21 06:37 config_aces_for_role.sql
-rwxr-xr-x 1 oracle oinstall 1551 May 21 07:15 config_aces_for_user.sql
-rwxr-xr-x 1 oracle oinstall 2118 May 19 07:07 dbc_aces.sql
-rwxr-xr-x 1 oracle oinstall 3736 May 21 03:43 dbms_cloud_install.sql
-rwxr-xr-x 1 oracle oinstall  691 May 21 06:16 grant_role.sql
-rwxr-xr-x 1 oracle oinstall  578 May 21 06:41 grant_user.sql
-rwxr-xr-x 1 oracle oinstall 1608 May 21 06:56 validate_user_config.sql
-rwxr-xr-x 1 oracle oinstall 1671 May 21 03:57 verify_aces.sql
[oracle@db19c dbc]$ echo $ORACLE_HOME
/u01/app/oracle/product/19.0.0.0/dbhome_1
[oracle@db19c dbc]$ $ORACLE_HOME/perl/bin/perl $ORACLE_HOME/rdbms/admin/catcon.pl -u sys/your_sys_password --force_pdb_mode 'READ WRITE' -b dbms_cloud_install -d /home/oracle/dbc -l /home/oracle/dbc dbms_cloud_install.sql
catcon::set_log_file_base_path: ALL catcon-related output will be written to [/home/oracle/dbc/dbms_cloud_install_catcon_35033.lst]

catcon::set_log_file_base_path: catcon: See [/home/oracle/dbc/dbms_cloud_install*.log] files for output generated by scripts

catcon::set_log_file_base_path: catcon: See [/home/oracle/dbc/dbms_cloud_install_*.lst] files for spool files, if any

catcon.pl: completed successfully
[oracle@db19c dbc]$
```

/home/oracle/dbcの下に、以下のログファイルが作成されましたので、それらを開きエラーがないことを確認します。
<pre>
[oracle@db19c dbc]$ ls -l dbms*.log dbms*.lst
-rw------- 1 oracle oinstall 12184 May 31 03:27 dbms_cloud_install0.log
-rw------- 1 oracle oinstall  6439 May 31 03:27 dbms_cloud_install1.log
-rw------- 1 oracle oinstall   444 May 31 03:26 dbms_cloud_install_catcon_35033.lst
[oracle@db19c dbc]$ grep -i error dbms*.log dbms*.lst
dbms_cloud_install0.log:No errors.
<略>
[oracle@db19c dbc]$
</pre>

CDBでインストール後の結果を確認します。
<strong>コマンド</strong>：
select con_id, owner, object_name, status, sharing, oracle_maintained from <strong>cdb_objects</strong> where object_name = 'DBMS_CLOUD' order by con_id;

```sql
SQL> show con_name;
CON_NAME
------------------------------
CDB$ROOT
SQL> col OWNER format a20
SQL> col OBJECT_NAME format a15
SQL> set linesize 100
SQL> set pagesize 10
SQL> select con_id, owner, object_name, status, sharing, oracle_maintained from cdb_objects where object_name = 'DBMS_CLOUD' order by con_id;
```

確認結果： (DBMS_CLOUDの状態は"<font color="blue">VALID</font>"です。)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/df2924bf-6d3c-40d9-00a8-5a667ea427f7.png" width="600">


PDBで確認します。
<strong>コマンド</strong>：
select owner, object_name, status, sharing, oracle_maintained from <strong>dba_objects</strong> where object_name = 'DBMS_CLOUD';

```sql
SQL> show con_name;
CON_NAME
------------------------------
DB19C_PDB1
SQL> select owner, object_name, status, sharing, oracle_maintained from dba_objects where object_name = 'DBMS_CLOUD';
```
確認結果： (DBMS_CLOUDの状態は"<font color="blue">VALID</font>"です。)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/023d86ee-3e60-9223-2fe9-5d3d03ad1bcd.png" width="500">


# STEP 3 - Walletの作成
HTTPSでオブジェクトストレージにアクセスするため、Walletファイルは必要です。
現在、Oracle はRU（リリース更新）の一部として証明書を出荷していませんが、MOSドキュメントから[db_cert.tar](https://objectstorage.us-phoenix-1.oraclecloud.com/p/QsLX1mx9A-vnjjohcC7TIK6aTDFXVKr0Uogc2DAN-Rd7j6AagsmMaQ3D3Ti4a9yU/n/adwcdemo/b/CERTS/o/dbc_certs.tar)のダウンロードは可能です。

<pre>
[oracle@db19c cert]$ pwd
/home/oracle/cert
[oracle@db19c cert]$ ll
total 12
-rw-rw-r-- 1 oracle oinstall 10240 May 31 03:09 dbc_certs.tar
[oracle@db19c cert]$ tar xvf dbc_certs.tar
BaltimoreCyberTrust.cer
DigiCert.cer
VeriSign.cer
[oracle@db19c cert]$
</pre>

tarファイル解凍後、以下のコマンドを実施し、Walletファイルを作成します。
<strong>コマンド</strong>：
cd <strong>/opt/oracle/dcs/commonstore/wallets/ssl</strong>
<strong>orapki wallet create</strong> -wallet . -pwd \<your_chosen_wallet_pw> -auto_login
<strong>orapki wallet add</strong> -wallet . -trusted_cert -cert /home/oracle/cert/<font color="blue">VeriSign.cer</font> -pwd \<your_chosen_wallet_pw>
<strong>orapki wallet add</strong> -wallet . -trusted_cert -cert /home/oracle/cert/<font color ="blue">BaltimoreCyberTrust.cer</font> -pwd \<your_chosen_wallet_pw>
<strong>orapki wallet add</strong> -wallet . -trusted_cert -cert /home/oracle/cert/<font color="blue">DigiCert.cer</font> -pwd \<your_chosen_wallet_pw>

<pre>
[oracle@db19c ~]$ cd /opt/oracle/dcs/commonstore/wallets/ssl
[oracle@db19c ssl]$ orapki wallet create -wallet . -pwd your_chosen_wallet_pw -auto_login
Oracle PKI Tool Release 19.0.0.0.0 - Production
Version 19.4.0.0.0
Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved.

Operation is successfully completed.
[oracle@db19c ssl]$ orapki wallet add -wallet . -trusted_cert -cert /home/oracle/cert/VeriSign.cer -pwd your_chosen_wallet_pw
Oracle PKI Tool Release 19.0.0.0.0 - Production
Version 19.4.0.0.0
Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved.

Operation is successfully completed.
[oracle@db19c ssl]$ orapki wallet add -wallet . -trusted_cert -cert /home/oracle/cert/BaltimoreCyberTrust.cer -pwd your_chosen_wallet_pw
Oracle PKI Tool Release 19.0.0.0.0 - Production
Version 19.4.0.0.0
Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved.

Operation is successfully completed.
[oracle@db19c ssl]$ orapki wallet add -wallet . -trusted_cert -cert /home/oracle/cert/DigiCert.cer -pwd your_chosen_wallet_pw
Oracle PKI Tool Release 19.0.0.0.0 - Production
Version 19.4.0.0.0
Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved.

Operation is successfully completed.
[oracle@db19c ssl]$
</pre>

作成されたWalletを確認します。
コマンド：<strong>orapki wallet display -wallet .</strong>
<pre>
[oracle@db19c ssl]$ pwd
/opt/oracle/dcs/commonstore/wallets/ssl
[oracle@db19c ssl]$ orapki wallet display -wallet .
Oracle PKI Tool Release 19.0.0.0.0 - Production
Version 19.4.0.0.0
Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved.

Requested Certificates:
User Certificates:
Trusted Certificates:
Subject:        CN=VeriSign Class 3 Public Primary Certification Authority - G5,OU=(c) 2006 VeriSign\, Inc. - For authorized use only,OU=VeriSign Trust Network,O=VeriSign\, Inc.,C=US
Subject:        CN=Baltimore CyberTrust Root,OU=CyberTrust,O=Baltimore,C=IE
Subject:        CN=DigiCert Global Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US
[oracle@db19c ssl]$
</pre>

# STEP 4 - Wallet場所の設定
作成されたWalletファイルを利用するため、<font color="blue">sqlnet.ora</font>の関連箇所を編集します。
※RACの場合、全ノードで実施してください。

<strong>ファイル名</strong>：$ORACLE_HOME/network/admin/sqlnet.ora
<strong>編集(追加)箇所</strong>：
WALLET_LOCATION=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY=/opt/oracle/dcs/commonstore/wallets/<font color="blue">ssl</font>)))

<pre>
[oracle@db19c admin]$ pwd
/u01/app/oracle/product/19.0.0.0/dbhome_1/network/admin
[oracle@db19c admin]$ cat sqlnet.ora
WALLET_LOCATION=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY=/opt/oracle/dcs/commonstore/wallets/ssl)))
..略..
</pre>

# STEP 5 - ACEs(Access Control Entries)の設定
HTTPSでオブジェクト・ストレージとの通信を許可するため、ACEsの作成は必要です。
ACEsを作成するのに、<font color="blue">dbc_aces.sql</font>の下記箇所を編集してから、実行します。

-- - SSL Wallet directory
<font color="Magenta">編集前</font>：define sslwalletdir=\<Set SSL Wallet Directory>
<font color="Blue">編集後</font>：define sslwalletdir=<strong>/opt/oracle/dcs/commonstore/wallets/ssl</strong>

プロキシサーバーを利用する場合、以下の行をアンコメントし、内容を編集します。
-- define proxy_uri=\<your proxy URI address>
-- define proxy_host=\<your proxy DNS name>
-- define proxy_low_port=\<your_proxy_low_port>
-- define proxy_high_port=\<your_proxy_high_port>

編集後、<strong>CDB</strong>にログインし、dbc_aces.sqlを実行します。

```sql
SQL> show con_name;

CON_NAME
------------------------------
CDB$ROOT
SQL> @dbc_aces.sql

Session altered.

old   9: principal_name => upper('&clouduser'),
new   9: principal_name => upper('C##CLOUD$SERVICE'),
Enter value for proxy_host:
old  16: -- host =>'&proxy_host',
new  16: -- host =>'',
Enter value for proxy_low_port:
old  17: -- lower_port => &proxy_low_port,
new  17: -- lower_port => ,
Enter value for proxy_high_port:
old  18: -- upper_port => &proxy_high_port,
new  18: -- upper_port => ,
old  21: -- principal_name => upper('&clouduser'),
new  21: -- principal_name => upper('C##CLOUD$SERVICE'),
old  29: wallet_path => 'file:&sslwalletdir',
new  29: wallet_path => 'file:/opt/oracle/dcs/commonstore/wallets/ssl',
old  32: principal_name => upper('&clouduser'),
new  32: principal_name => upper('C##CLOUD$SERVICE'),

PL/SQL procedure successfully completed.

old   4: execute immediate 'alter database property set ssl_wallet=''&sslwalletdir''';
new   4: execute immediate 'alter database property set ssl_wallet=''/opt/oracle/dcs/commonstore/wallets/ssl''';
Enter value for proxy_uri:
old   8: -- execute immediate 'alter database property set http_proxy=''&proxy_uri''';
new   8: -- execute immediate 'alter database property set http_proxy=''''';

PL/SQL procedure successfully completed.


Session altered.

SQL>
```

実行後、設定内容を確認します。

```sql
SQL> col PROPERTY_NAME format a15
SQL> col PROPERTY_VALUE format a40
SQL> col DESCRIPTION format a30
SQL> set linesize 100
SQL> select * from database_properties where property_name in ('SSL_WALLET','HTTP_PROXY');

PROPERTY_NAME   PROPERTY_VALUE                           DESCRIPTION
--------------- ---------------------------------------- ------------------------------
SSL_WALLET      /opt/oracle/dcs/commonstore/wallets/ssl  Location of SSL Wallet

SQL>
```

# STEP 6 - DBMS_CLOUDの設定を検証
ここまで、Walletの作成とACEsの設定を実施しましたが、正しく設定されているかどうかを検証します。

事前に用意した<font color="blue">verify_aces.sql</font>を開き、以下の箇所を編集します。

<font color="Magenta">編集前</font>：define sslwalletdir=\<Set SSL Wallet Directory>
<font color="Blue">編集後</font>：define sslwalletdir=<strong>/opt/oracle/dcs/commonstore/wallets/ssl</strong>

<font color="Magenta">編集前</font>：define sslwalletpwd=\<Set SSL Wallet password>
<font color="Blue">編集後</font>：define sslwalletpwd=\<Wallet作成時、指定したパスワード>

<font color="Magenta">編集前</font>：GET_PAGE('https://<font color="">objectstorage</font>.<font color="blue">eu-frankfurt-1</font>.oraclecloud.com');
<font color="Blue">編集後</font>：GET_PAGE('https://<font color="">objectstorage</font>.<font color="blue">ap-tokyo-1</font>.oraclecloud.com');
※リージョンキーを置き換えます。この例は東京リージョンを利用します。

編集後、SYSユーザでCDBかPDBにログインし、verify_aces.sqlを実行します。
"<font color="blue">valid response</font>"が表示されるのを確認します。

```sql
SQL> @verify_aces.sql
old   1: CREATE OR REPLACE PROCEDURE &clouduser..GET_PAGE(url IN VARCHAR2) AS
new   1: CREATE OR REPLACE PROCEDURE C##CLOUD$SERVICE.GET_PAGE(url IN VARCHAR2) AS
old  13: wallet_path => 'file:&sslwalletdir',
new  13: wallet_path => 'file:/opt/oracle/dcs/commonstore/wallets/ssl',
old  14: wallet_password => '&sslwalletpwd');
new  14: wallet_password => 'SSL Wallet password');

Procedure created.

old   2: &clouduser..GET_PAGE('https://objectstorage.ap-tokyo-1.oraclecloud.com');
new   2: C##CLOUD$SERVICE.GET_PAGE('https://objectstorage.ap-tokyo-1.oraclecloud.com');
valid response

PL/SQL procedure successfully completed.

old   1: drop procedure &clouduser..GET_PAGE
new   1: drop procedure C##CLOUD$SERVICE.GET_PAGE

Procedure dropped.

SQL>
```

ここまで、DBMS_CLOUDのインストールと設定は完了です。これから、対象のユーザ・ロールへの権限付与を実施します。

# STEP 7 - ユーザ・ロールへの権限付与

以下の２つ方法があります。
1. 直接に、対象ユーザにDBMS_CLOUDの利用権限を付与します。(<font color="blue">grant_user.sql</font>を実行) 
2. 対象ユーザが付けられたロールに、DBMS_CLOUDの利用権限を付与します。(<font color="blue">grant_role.sql</font>を実行)

この例は、方法１を利用し、PDBの<font color="blue">USER01</font>というユーザに権限を付与します。
<font color="blue">grant_user.sql</font>の以下の箇所を編集します。

<font color="Magenta">編集前</font>：define username='SCOTT'
<font color="Blue">編集後</font>：define username='<strong>USER01</strong>'

編集後、SYSかSYSTEMユーザでPDBにログインし、grant_user.sqlを実行します。

```sql
SQL> alter session set container=DB19c_PDB1;

Session altered.

SQL> @grant_user.sql

Grant succeeded.


Grant succeeded.


Grant succeeded.

SQL>
```

# STEP 8 - ユーザ・ロールのため、ACEsを設定
STEP7と同様、２つ方法があります。
1. 直接に対象ユーザに設定した場合、<font color="blue">config_aces_for_user.sql</font>を編集し実行します。
2. ロールに設定した場合、<font color="blue">config_aces_for_role.sql</font>を編集し実行します。

この例は、STEP7と同様、対象ユーザに設定しますので、<font color="blue">config_aces_for_user.sql</font>を編集します。編集箇所は、以下となります。

<font color="Magenta">編集前</font>：define username='SCOTT'
<font color="Blue">編集後</font>：define username='<strong>USER01</strong>'

<font color="Magenta">編集前</font>：define sslwalletdir=\<Set SSL Wallet Directory>
<font color="Blue">編集後</font>：define sslwalletdir=<strong>/opt/oracle/dcs/commonstore/wallets/ssl</strong>

編集後、SYSかSYSTEMユーザでPDBにログインし、config_aces_for_user.sqlを実行します。

```sql
SQL> alter session set container=DB19c_PDB1;

Session altered.

SQL> @config_aces_for_user.sql

Session altered.

old   9: principal_name => upper('&clouduser'),
new   9: principal_name => upper('USER01'),
old  17: -- host =>'&proxy_host',
new  17: -- host =>'<your',
old  18: -- lower_port => &proxy_low_port,
new  18: -- lower_port => <your_proxy_low_port>,
old  19: -- upper_port => &proxy_high_port,
new  19: -- upper_port => <your_proxy_high_port>,
old  22: -- principal_name => upper('&clouduser'),
new  22: -- principal_name => upper('USER01'),
old  30: wallet_path => 'file:&sslwalletdir',
new  30: wallet_path => 'file:/opt/oracle/dcs/commonstore/wallets/ssl',
old  33: principal_name => upper('&clouduser'),
new  33: principal_name => upper('USER01'),

PL/SQL procedure successfully completed.


Session altered.

SQL>
```

# STEP 9 - クレデンシャルの作成と検証
OCIオブジェクト・ストレージ上のデータをアクセスするため、クレデンシャルは必要です。
OCIユーザと<font color="blue">認証トークン</font>を事前に用意しておいてください。

対象ユーザ(USER01)でPDBにログインします。

```sql
SQL> show con_name;

CON_NAME
------------------------------
DB19C_PDB1
SQL> show user;
USER is "USER01"
SQL>
```

DBMS_CLOUDを利用し、クレデンシャルを作成します。（認証トークンは事前に準備してください。）
<strong>スクリプト</strong>：
BEGIN
<font color="blue">DBMS_CLOUD.CREATE_CREDENTIAL</font>(
<strong>credential_name</strong> => 'your credential name',
<strong>username</strong> => 'OCI user name',
<strong>password</strong> => 'auth token generated for OCI user'
);
END;
/

```sql
SQL> BEGIN
  2  DBMS_CLOUD.CREATE_CREDENTIAL(
  3  credential_name => 'TEST_CRED',
  4  username => 'oracleidentitycloudservice/user_name(略)',
  5  password => 'auth token(略)'
  6  );
  7  END;
  8  /

PL/SQL procedure successfully completed.

SQL>
```

作成後、以下のコマンドで、OCI上のバケットをアクセスし、オブジェクトの一覧を取得します。
select * from <font color="blue">dbms_cloud.list_objects</font>(<'CredentialName'>,'https://objectstorage.<strong>region</strong>.oraclecloud.com/n/<strong>ObjectStorageNameSpace</strong>/b/<strong>BucketName</strong>/o/');

\<region>: ap-tokyo-1
\<ObjectStorageNameSpace>: 確認方法は[ドキュメント](https://docs.oracle.com/ja-jp/iaas/Content/Object/Tasks/understandingnamespaces.htm)をご参照ください。
<font color="blue">OCIのテナンシー名ではない</font>ので、ご注意ください。

```sql
SQL> col OBJECT_NAME format a15
SQL> col CHECKSUM format a35
SQL> col CREATED format a10
SQL> col LAST_MODIFIED format a40
SQL> set linesize 120
SQL> select * from dbms_cloud.list_objects('TEST_CRED','https://objectstorage.ap-tokyo-1.oraclecloud.com/n/ObjectStorageNameSpace(略)/b/Bucket1/o/');

OBJECT_NAME          BYTES CHECKSUM                            CREATED    LAST_MODIFIED
--------------- ---------- ----------------------------------- ---------- ----------------------------------------
channels.txt           102 d892cb82bc99d45dc1119e04e44988c7               18-MAY-21 03.12.33.705000 AM +00:00

SQL>
```

今のユーザの設定を検証するため、<font color="blue">validate_user_config.sql</font>の内容を編集してから、実行します。編集箇所は、以下となります。

<font color="Magenta">編集前</font>：define username='SCOTT'
<font color="Blue">編集後</font>：define username='<strong>USER01</strong>'

<font color="Magenta">編集前</font>：define sslwalletdir=\<Set SSL Wallet Directory>
<font color="Blue">編集後</font>：define sslwalletdir=<strong>/opt/oracle/dcs/commonstore/wallets/ssl</strong>

<font color="Magenta">編集前</font>：define sslwalletpwd=\<Set SSL Wallet password>
<font color="Blue">編集後</font>：define sslwalletpwd=\<Wallet作成時、指定したパスワード>

<font color="Magenta">編集前</font>：GET_PAGE('https://<font color="">objectstorage</font>.<font color="blue">eu-frankfurt-1</font>.oraclecloud.com');
<font color="Blue">編集後</font>：GET_PAGE('https://<font color="">objectstorage</font>.<font color="blue">ap-tokyo-1</font>.oraclecloud.com');

編集後、USER01ユーザでPDBにログインし、validate_user_config.sqlを実行します。
"<font color="blue">valid response</font>"が表示されるのを確認します。

```sql
SQL> show user;
USER is "USER01"
SQL> @validate_user_config.sql
old   1: CREATE OR REPLACE PROCEDURE &clouduser..GET_PAGE(url IN VARCHAR2) AS
new   1: CREATE OR REPLACE PROCEDURE USER01.GET_PAGE(url IN VARCHAR2) AS
old  13: wallet_path => 'file:&sslwalletdir',
new  13: wallet_path => 'file:/opt/oracle/dcs/commonstore/wallets/ssl',
old  14: wallet_password => '&sslwalletpwd');
new  14: wallet_password => 'SSL Wallet password');

Procedure created.

old   2: &clouduser..GET_PAGE('https://objectstorage.ap-tokyo-1.oraclecloud.com');
new   2: USER01.GET_PAGE('https://objectstorage.ap-tokyo-1.oraclecloud.com');
valid response

PL/SQL procedure successfully completed.

old   1: drop procedure &clouduser..GET_PAGE
new   1: drop procedure USER01.GET_PAGE

Procedure dropped.

SQL>
```

# STEP10 - オブジェクト・ストレージからCSVファイルをDBにコピー
この例は、以下のようなCSVファイルを利用します。OCI上のバケットに保存されます。

バケット名：<font color="blue">Bucket1</font>
オブジェクト名：<font color="blue">channels.txt</font>
オブジェクトの中身：
<pre>
S,Direct Sales,Direct
T,Tele Sales,Direct
C,Catalog,Indirect
I,Internet,Indirect
P,Partners,Others
</pre>

事前にテーブルを作成しておきます。(ユーザ"USER01")
<strong>コマンド</strong>：
CREATE TABLE CHANNELS
   (channel_id CHAR(1),
    channel_desc VARCHAR2(20),
    channel_class VARCHAR2(20)
   );
/

```sql
SQL> show user;
USER is "USER01"
SQL> CREATE TABLE CHANNELS
  2     (channel_id CHAR(1),
  3      channel_desc VARCHAR2(20),
  4      channel_class VARCHAR2(20)
  5     );

Table created.
```

DBMS_CLOUD.COPY_DATAを利用し、データをコピーします。
<strong>コマンド</strong>：
BEGIN
 <font color="blue">DBMS_CLOUD.COPY_DATA</font>(
    <strong>table_name</strong> =>'CHANNELS',
    <strong>credential_name</strong> =>'your credential name',
    <strong>file_uri_list</strong> =>'https://<font color="">objectstorage</font>.\<region>.oraclecloud.com/n/\<ObjectStorageNameSpace>/b/\<BucketName>/o/\<ObjectName>',
    <strong>format</strong> => json_object('delimiter' value ',')
 );
END;
/


実施例：

```sql
SQL> BEGIN
  2   DBMS_CLOUD.COPY_DATA(
  3      table_name =>'CHANNELS',
  4      credential_name =>'TEST_CRED',
  5      file_uri_list =>'https://objectstorage.ap-tokyo-1.oraclecloud.com/n/ObjectStorageNameSpace(略)/b/Bucket1/o/channels.txt',
  6      format => json_object('delimiter' value ',')
  7   );
  8  END;
  9  /

PL/SQL procedure successfully completed.

SQL>
```

コピー後、テーブルの中身を確認します。

```sql
SQL> select * from CHANNELS;

C CHANNEL_DESC         CHANNEL_CLASS
- -------------------- --------------------
S Direct Sales         Direct
T Tele Sales           Direct
C Catalog              Indirect
I Internet             Indirect
P Partners             Others

SQL>
```

ここまで、CSVファイルの導入例は完了です。

# STEP11 - オブジェクト・ストレージからDUMPファイルをDBにインポート

CSVのようなテキストファイルだけではなく、オブジェクト・ストレージ上のDUMPファイルもDBに導入できます。

<strong>実施ステップ</strong>：
1. <font color="blue">DBMS_CLOUD.GET_OBJECT</font>で、オブジェクト・ストレージからDUMPファイルを取得し、ディレクトリに保存します。
2. <font color="blue">impdp</font>コマンドで、通常のインポート処理を実施します。

__事前準備__
DUMPファイル用のディレクトリを作成し、権限を対象ユーザ(USER01)に付与します。
("/u01/app/oracle/dmp"を事前に作成しておきます。)

```sql
SQL> show user;
USER is "SYSTEM"
SQL> CREATE OR REPLACE DIRECTORY TEST_DIR AS '/u01/app/oracle/dmp/';

Directory created.

SQL> GRANT READ, WRITE ON DIRECTORY TEST_DIR TO USER01;

Grant succeeded.

SQL>
```

expdpでテーブルをエクスポートします。

<pre>
[oracle@db19c dmp]$ pwd
/u01/app/oracle/dmp
[oracle@db19c dmp]$ expdp USER01/password@DB19C_PDB1 tables=CHANNELS directory=TEST_DIR dumpfile=channels.dmp logfile=expdp_channels.log

Export: Release 19.0.0.0.0 - Production on Thu Jun 3 07:57:33 2021
Version 19.10.0.0.0

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

Connected to: Oracle Database 19c Standard Edition 2 Release 19.0.0.0.0 - Production
Starting "USER01"."SYS_EXPORT_TABLE_01":  USER01/********@DB19C_PDB1 tables=CHANNELS directory=TEST_DIR dumpfile=channels.dmp logfile=expdp_channels.log
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER
Processing object type TABLE_EXPORT/TABLE/TABLE
. . exported "USER01"."CHANNELS"                         6.031 KB       5 rows
ORA-39173: Encrypted data has been stored unencrypted in dump file set.
Master table "USER01"."SYS_EXPORT_TABLE_01" successfully loaded/unloaded
******************************************************************************
Dump file set for USER01.SYS_EXPORT_TABLE_01 is:
  /u01/app/oracle/dmp/channels.dmp
Job "USER01"."SYS_EXPORT_TABLE_01" successfully completed at Thu Jun 3 07:58:04 2021 elapsed 0 00:00:30

[oracle@db19c dmp]$
</pre>

オブジェクト・ストレージへのファイル転送は、ここで省略します。
転送後、以下のコマンドで確認できます。
select * from <font color="blue">dbms_cloud.list_objects</font>(<'CredentialName'>,'https://objectstorage.<strong>region</strong>.oraclecloud.com/n/<strong>ObjectStorageNameSpace</strong>/b/<strong>BucketName</strong>/o/');

```sql
SQL> show user
USER is "USER01"
SQL> col OBJECT_NAME format a15
SQL> col CHECKSUM format a35
SQL> col CREATED format a10
SQL> col LAST_MODIFIED format a40
SQL> set linesize 120
SQL> select * from dbms_cloud.list_objects('TEST_CRED','https://objectstorage.ap-tokyo-1.oraclecloud.com/n/ObjectStorageNameSpace(略)/b/Bucket1/o/');

OBJECT_NAME          BYTES CHECKSUM                            CREATED    LAST_MODIFIED
--------------- ---------- ----------------------------------- ---------- ----------------------------------------
channels.dmp        176128 9c8b52350d09f5ab2f4bed2ace7b140b               03-JUN-21 08.05.37.762000 AM +00:00
channels.txt           102 d892cb82bc99d45dc1119e04e44988c7               18-MAY-21 03.12.33.705000 AM +00:00

SQL>
```

__DUMPファイルの取得__
DBMS_CLOUD.GET_OBJECTで、DUMPファイルを取得し、ディレクトリに保存します。
("USER01"で実行)

<strong>コマンド</strong>：
BEGIN
 <font color="blue">DBMS_CLOUD.GET_OBJECT</font>(
    <strong>credential_name</strong> =>'your credential name',
    <strong>object_uri</strong> =>'https://<font color="">objectstorage</font>.\<region>.oraclecloud.com/n/\<ObjectStorageNameSpace>/b/\<BucketName>/o/\<ObjectName>',
    <strong>directory_name</strong> => 'your directory name');
END;
/

もし以下のようなエラーが発生した場合、ユーザ"<font color="blue">C##CLOUD$SERVICE</font>"にディレクトリへのアクセス権限を付与すれば回避できます。
<pre>
ERROR at line 1:
ORA-20000: ORA-29289: directory access denied
ORA-06512: at "C##CLOUD$SERVICE.DBMS_CLOUD", line 921
ORA-06512: at "C##CLOUD$SERVICE.DBMS_CLOUD", line 2411
ORA-06512: at line 2
</pre>

実施例：

```sql
SQL> show user
USER is "SYSTEM"
SQL> GRANT READ, WRITE ON DIRECTORY TEST_DIR TO C##CLOUD$SERVICE;

Grant succeeded.

SQL>
```

"USER01"でDBMS_CLOUD.GET_OBJECTを実施します。

```sql
SQL> show user
USER is "USER01"
SQL> BEGIN
  2       DBMS_CLOUD.GET_OBJECT(
  3       credential_name => 'TEST_CRED',
  4       object_uri => 'https://objectstorage.ap-tokyo-1.oraclecloud.com/n/ObjectStorageNameSpace(略)/b/Bucket1/o/channels.dmp',
  5       directory_name => 'TEST_DIR');
  6  END;
  7  /

PL/SQL procedure successfully completed.

SQL>
```

取得後、ディレクトリの下にDUMPファイルが作成されます。（既存ファイルがある場合、上書きされます。）
<pre>
[oracle@db19c dmp]$ pwd
/u01/app/oracle/dmp
[oracle@db19c dmp]$ ls -l channels.dmp
-rw-r--r-- 1 oracle asmadmin 176128 Jun  3 10:05 channels.dmp
[oracle@db19c dmp]$
</pre>

__インポート処理__
これから、impdpでインポート処理を実施します。（この例は、カラのテーブルにインポートします。）

<pre>
[oracle@db19c dmp]$ impdp USER01/password@DB19C_PDB1 tables=CHANNELS directory=TEST_DIR dumpfile=channels.dmp logfile=impdp_channels.log ignore=y

Import: Release 19.0.0.0.0 - Production on Thu Jun 3 10:15:51 2021
Version 19.10.0.0.0

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

Connected to: Oracle Database 19c Standard Edition 2 Release 19.0.0.0.0 - Production
Legacy Mode Active due to the following parameters:
Legacy Mode Parameter: "ignore=TRUE" Location: Command Line, Replaced with: "table_exists_action=append"
Master table "USER01"."SYS_IMPORT_TABLE_01" successfully loaded/unloaded
Starting "USER01"."SYS_IMPORT_TABLE_01":  USER01/********@DB19C_PDB1 tables=CHANNELS directory=TEST_DIR dumpfile=channels.dmp logfile=impdp_channels.log table_exists_action=append
Processing object type TABLE_EXPORT/TABLE/TABLE
Table "USER01"."CHANNELS" exists. Data will be appended to existing table but all dependent metadata will be skipped due to table_exists_action of append
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
. . imported "USER01"."CHANNELS"                         6.031 KB       5 rows
Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER
Job "USER01"."SYS_IMPORT_TABLE_01" successfully completed at Thu Jun 3 10:15:56 2021 elapsed 0 00:00:03

[oracle@db19c dmp]$
</pre>

インポート実施後、テーブルの内容を確認します。

```sql
SQL> show user
USER is "USER01"
SQL> select * from channels;

C CHANNEL_DESC         CHANNEL_CLASS
- -------------------- --------------------
S Direct Sales         Direct
T Tele Sales           Direct
C Catalog              Indirect
I Internet             Indirect
P Partners             Others

SQL>
```

ここまで、DUMPファイルの導入例は完了です。
上記方法は、AWS S3とAzure Blobにも適用しますので、導入例は、以下の関連記事をご参照ください。

__以上__

----

__関連記事__
[オラクル・クラウドの個人ブログ一覧](https://qiita.com/liu-wei/items/10152a4fec813c1b7d98)
[AWS S3からOracle DBにデータを導入する](https://qiita.com/liu-wei/items/2ed58265519531d09e97)
[Azure BlobからOracle DBにデータを導入する](https://qiita.com/liu-wei/items/17b3b49735b458e3412d)
[Oracle DBからOCIオブジェクト・ストレージへデータをエクスポートする手順](https://qiita.com/liu-wei/items/61f9df69b1b2a58c87c9)
[マウント・ポイントを経由して、Oracle Base DBからオブジェクト・ストレージへデータをエクスポートする手順](https://qiita.com/liu-wei/items/3b28dcae87f704ba134b)