Docker でOracle試した時に詰まったポイント

# dockerでOracle使ってみたい！
mac用oracleは無いと知って…
以下記事を参考とさせていただき、どうにかこうにか動くところまではできました！

- [macOSでOracle Database使いたい]
(https://qiita.com/yuttoku/items/f9aa9c3caf17d95c81b7)

が…その先でいろいろ詰まったポイントがあったので、自分用にメモしておきます。もし同じ事象にハマっている人の参考となれば幸い。

# systemユーザーのパスワードを設定したい
上記記事通りにやると、コンテナをビルドしたときにOracleのパスワードは自動で設定されるのですが、なぜかsystemユーザーにはパスワードが設定されていないっぽいです。
ログ見る限りだと、sysユーザーと同じパスワードが設定されているっぽいのですが、password deniedで弾かれます。なので、パスワードを新たに設定し直したいと思います。

### パスワード設定shellを使う
Oracle公式のdocker用イメージからコンテナ作成していれば、パスワード設定用のシェルが用意されていますので、それ使います。コンテナ側のホームディレクトリにシンボリックリンクがあります。
引数１に指定した文字列が新しいパスワードになります。これでsysとsystemユーザーのパスワードが再設定されます。
`bash setPassword.sh [引数1]`


### 備考:コンテナビルド時の自動設定パスワード確認
 `docker logs [コンテナ名]`
これでコンテナをビルドしたときのログを表示してくれます。１行目に自動設定パスワードが記載されています。

```
$ docker logs docker_oracle
ORACLE PASSWORD FOR SYS, SYSTEM AND PDBADMIN: HzGv+JeJEdE=1  <--- これ

LSNRCTL for Linux: Version 12.2.0.1.0 - Production on 07-APR-2019 12:10:54

Copyright (c) 1991, 2016, Oracle.  All rights reserved.

Starting /opt/oracle/product/12.2.0.1/dbhome_1/bin/tnslsnr: please wait...

TNSLSNR for Linux: Version 12.2.0.1.0 - Production
System parameter file is /opt/oracle/product/12.2.0.1/dbhome_1/network/admin/listener.ora
Log messages written to /opt/oracle/diag/tnslsnr/975137a8234e/listener/alert/log.xml
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1)))
Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))
・・・
（〜以下略〜）
```
前述の通り、見た感じsystemユーザーにもパスワード設定されているっぽいんだけどなぁ…



# Oracleで通常権限のユーザーを作成したい
コンテナをビルドした時点では、普通にインストールした場合と同じく、sysユーザーとsystemユーザーしかありません。これらの配下に新しいテーブル作るのはなんだかなぁ…と言うわけで通常権限のユーザーを作成したくなりました。
早速、sysまたはsystemユーザーでSQL*Plusを起動し、create userしようとすると…ORA-65096で怒られます。

### 前提知識・下準備
ググったところ、以下が原因っぽい。

- [スキーマ（ユーザ）作成時に「ORA-65096」～Oracle 12cのアーキテクチャはここが違う～:DBMoto] 
(https://www.climb.co.jp/blog_dbmoto/archives/1272)

簡単に要約すると…

- Oracle12cはCDB(マルチテナントコンテナDB）配下にPDB（プラガブルDB）があるイメージだよ
- CDBにはユーザースキーマが作れない、PDBに作る必要があるよ
- CDBからはPDBは見えないよ

…ということらしい。詳しいことはよくわからんが、とりあえずPDBに接続してcreate userする必要がある模様。
上記記事によれば、PDB接続するためには、まずtnsnames.oraを編集する必要があるみたいです。
当該ファイルは、ここに格納されていました。
`/opt/oracle/oradata/dbconfig/ORCLCDB/tnsnames.ora`
PDBの接続情報がない場合は、上記[参考情報]をお手本に追記しましょう。
なお、Oracle公式イメージからビルドしていれば、以下の様に最初から定義されているっぽいです。

```oracle:tnsnames.oraの中身
ORCLCDB=localhost:1521/ORCLCDB
ORCLPDB1= 
(DESCRIPTION = 
  (ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))
  (CONNECT_DATA =
    (SERVER = DEDICATED)
    (SERVICE_NAME = ORCLPDB1)
  )
)
```

## PDBの起動・接続
sysかsystemでSQL*Plusを起動します。
まずは以下のコマンドで、現在はCDBに接続されていることを確認します。
`show con_name;`

```:実行例
SQL> show con_name
CON_NAME
------------------------------
CDB$ROOT
```

お次に、PDBを起動します。
`alter pluggable database [PDB名] open;`
PDB名は、前述のdocker logsとかtnsnames.oraに書いてます。
以下実行例です（が、すでに起動しているのでエラーとなっています…結果オーライ）。

```:実行例
SQL> alter pluggable database ORCLPDB1 open;
alter pluggable database orclpdb1 open
*
ERROR at line 1:
ORA-65019: pluggable database ORCLPDB1 already open
```

次に、PDBへ接続します
`alter session set container = [PDB名];`

```:実行例
SQL> alter session set container = ORCLPDB1;

Session altered.

SQL> show con_name

CON_NAME
------------------------------
ORCLPDB1
```

con_nameがPDB名に変わっていることで、PDBへの接続できたことがわかります。
これでやっと、create userができるようなっているはずです。

### 作成したユーザーテーブルへの接続
上記手順を踏めば、ユーザーテーブルを作ることができるのはわかりました。では、作ったユーザーテーブルへ接続するには？
一旦SQL*Plusを抜けたあと、以下の要領でSQL*Plusを起動します。
`sqlplus [ユーザー名]/[パスワード]@[ホスト名]:[ポート]/[PDB名]`
ややごちゃごちゃしてますが、大抵の場合ホスト名はlocalhost、ポートは1521なんじゃないでしょうか。
PDB名は前述の通り。

というわけで、やっと通常権限のユーザーでOracle使えるようになりました。

### 備考:SQLDeveloperで接続する時
PDBに作ったテーブルにSqlDeveloperで接続する場合は、SID指定ではなく、サービス名にPDB名を指定してやればいいようです。

# 最後に
以下、不明点とか今後の展望とか。

- ユーザーテーブル作れなかったのは、docker特有のなのか、oracle12c特有の事象なのか。手元にあるoracleの参考書では、普通に（CDBとかPDBとかの意識なく）systemユーザーでcreate userできてるんだけど。
- 一旦SQL*Plus終了すると、またPDBへの接続からやり直し？どこからどこまでの手順を繰り返す必要があるのか、不明確。
- 最終目標はSpringFrameworkとMybatise3.xの連携で今回作ったテーブルを利用すること。そこで躓きあれば、本記事追記するなり別記事作るなりしよう。