PostgreSQL on AWS RDSで利用できるOracle Database互換関数の紹介

たまには Oracle Database 以外の話を書きます。本記事は [PostgreSQL Advent Calendar 2018](https://qiita.com/advent-calendar/2018/postgresql) の Day 4 のエントリです。

# Oracle Database から PostgreSQL への移行
Oracle Database ユーザーが PostgreSQL にアプリケーションの移行を行う場合、越えなければならないハードルが数多くあります。データの移行は全体移行、差分移行共に比較的ツールがそろっており、技術的な難易度は低いと思われます。例えばAmazon AWS には [Amazon Data Migration Service](https://aws.amazon.com/jp/dms/) (DMS) が提供されていて、安価にデータ移行を行うことができます（データ型の差異など考えなければならないことは多いですが）。
　アプリケーション移行で最も移行が難しいと思われる部分は、発行する SQL 文や PL/SQL で作成されたストアド・プログラムの違いを吸収することだと思います。

# Schema Conversion Tool
  [AWS Schema Conversion Tool] (https://docs.aws.amazon.com/SchemaConversionTool/index.html) (SCT) は、異なるデータベース・プロダクト間でテーブルやインデックスなどの定義や、ストアド・プログラムの変換を行うことができる優れたツールです。
しかし、異なるデータベース間では関数名や構文の単純変換では対応できない例がいくつもあります。例えば同一の関数名ながら値によって微妙に動作が異なる関数があります。 

SUBSTR 関数

```
Oracle Database
SQL> SELECT SUBSTR('DATA', 1, 2) SUB1, SUBSTR('DATA', 0, 2) SUB2 FROM DUAL;

SUB1   SUB2
------ ------
DA     DA


PostgreSQL
postgres=> SELECT SUBSTR('DATA', 1, 2) SUB1, SUBSTR('DATA', 0, 2) SUB2;
 sub1 | sub2
------+------
 DA   | D
(1 row)
```

また、機能が豊富な Oracle Database にしか存在しないパッケージやテーブルに PL/SQL プロシージャが依存している場合もあります。

# Oracle Database 互換関数
移行先のデータベース上で既存のプログラムが問題無く動作するために、SCT は、Oracle Database 互換の関数やテーブルを提供しています。互換関数群は[拡張パック](https://docs.aws.amazon.com/ja_jp/SchemaConversionTool/latest/userguide/CHAP_ExtensionPack.html)と呼ばれます。拡張パックは SCT から接続先の PostgreSQL に簡単にインストールすることができます。

## スキーマ
拡張パックに含まれる互換関数やテーブルはすべて aws_oracle_ext スキーマに格納されます。

## 関数
以下の関数が提供されます。

- ADD_MONTHS
- ASCIISTR
- CHARTOROWID
- CURRENT_{DATE | TIMESTAMP}
- FROM_TZ
- INSTR
- LAST_DAY
- LIMIT
- LOCALTIMESTAMP
- MONTHS_BETWEEN
- REGEXP_{COUNT | INSTR | LIKE | REPLACE | SUBSTR}
- SYS_CONTEXT
- TABLE
- TO_{CHAR | DATE | NUMBER}
- TRIM
- TRUNC
- USERENV
- 配列操作
- ネストテーブル関連

実行例

```
postgres=> SELECT aws_oracle_ext.add_months(current_timestamp::timestamp without time zone, 1);
         add_months
----------------------------
 2019-01-03 16:48:04.542403
(1 row)

postgres=> SELECT aws_oracle_ext.last_day(aws_oracle_ext.sysdate());
      last_day
---------------------
 2018-12-31 16:50:36
(1 row)

```
##  パッケージ
拡張パックには以下のパッケージに対応する関数が提供されますが、すべての関数を提供しているわけではありません。関数名は「aws_oracle_ext.{パッケージ名}${関数名}」の形式で提供されます。

- DMS_ASSERT
- DBMS_JOB
- DBMS_LOCK
- DBMS_OBFUSCATION_TOOLKIT
- DBMS_RANDOM
- DBMS_SESSION
- DBMS_SQL
- UTL_ENCODE
- UTL_SMTP
- UTL_UTL

実行例

```
postgres=> SELECT aws_oracle_ext.dbms_random$normal();
 dbms_random$normal
---------------------
 -0.0124097416232978
(1 row)
```

## テーブル
拡張パックには以下のテーブル／ビューが提供されます。

- V$VERSION
- V$INSTANCE
- V$NLS_PARAMETERS
- SYS_{USER | ALL | DBA}_TAB_COLS
- SYS_{USER | ALL | DBA}_TAB_COLUMNS
- SYS_{USER | ALL | DBA}_TABLES
- SYS_{USER | ALL | DBA}_USERS
- SYS_{USER | ALL | DBA}_VIEWS
- SYS_{USER | ALL | DBA}_CONSTRAINTS
- SYS_{USER | ALL | DBA}_OBJECTS
- SYS_{USER | ALL | DBA}_SEQUENCES
- その他

実行例

```
postgres=> SELECT * FROM aws_oracle_ext.v$version;
-[ RECORD 1 ]------------------------------------------------------------------------
banner | PostgreSQL 9.6.9 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.9.3, 64-bit

postgres=> SELECT * FROM aws_oracle_ext.v$instance;
-[ RECORD 1 ]----+-----------------------------
instance_number  | 1
instance_name    | 000.000.000.000
host_name        | 000.000.000.000/32:5432
version          | 9.6.9 on x86_64-pc-linux-gnu
startup_time     | 2018-12-03 06:30:02.94747+00
status           | OPEN
parallel         | NO
THREAD#          | 1
archiver         | FAILED
log_switch_wait  |
logins           | ALLOWED
shutdown_pending | NO
database_status  | ACTIVE
instance_role    | PRIMARY_INSTANCE
active_state     | NORMAL
blocked          | NO

```

# Microsoft SQL Server では？
Microsoft が提供する [SQL Server Migration Assistance] (https://docs.microsoft.com/ja-jp/sql/ssma/sql-server-migration-assistant?view=sql-server-2017) (SSMA) は SCT とよく似たアーキテクチャを持っており、Oracle Database 互換の関数群を提供しています。

# 明日は
明日の PostgreSQL Advent Calendar 2018 は [@yamamo-iさん](https://qiita.com/yamamo-i) の「運用から見る逆引きRDS for PostgreSQL」の予定です。