Oracle Cloud Infrastructure（OCI）Data Integration で差分データ連携を試してみた

2020年9月、Oracle Cloud Infrastructure（OCI）に、簡単にデータ連携できるツールとして、Data Integration が実装されました。

データ連携するにあたって、小さなデータであれば、必要な都度、全件を連携すればよいのですが（いわゆる「洗い替え」）、売上トランザクションなどの大きなデータを毎回全件連携するのは効率が悪いため、例えばその日の売上データだけを切り出して連携するような差分データ連携ができると便利です。

今回は、そんな差分データ連携を OCI Data Integrationで試してみた結果を記載しています。

### 0.前提事項

前提事項としては、[@sugimountさん](https://qiita.com/sugimount)の[「[Oracle Cloud] Data Integration のチュートリアルをやってみた」](https://qiita.com/sugimount/items/155b13acf17e769c9d9f)をベースに、事前準備やデータ・アセットの作成、データフローの作成、タスクの実行などを理解していることとして、ここではフィルターの設定にフォーカスして記載していきます。

今回は、２つの Oracle Databaseをソースとターゲットに見立てていますが、特にデータ・アセットの種類による違いはありません。

### 1.データの準備

以下のような売上表をソース側とターゲット側に準備します。

```
SQL> desc uriage
 名前                                    NULL?    型
 ----------------------------------------- -------- ----------------------------
 TRAN_NO                                            NUMBER(6)
 CUST                                               VARCHAR2(100)
 KINGAKU                                            NUMBER(8)
 TRAN_DATE                                          DATE
```

ソース側には以下のデータを準備します。

```
SQL> select * from uriage;

   TRAN_NO CUST                    KINGAKU TRAN_DAT
---------- -------------------- ---------- --------
    120101 大阪商会                  25000 20-12-01
    120201 広島デパート              50000 20-12-02
    120202 福岡電機                 100000 20-12-02
    120301 岡山産業                  20000 20-12-03
    120302 神戸サービス              40000 20-12-03
    120303 大阪商会                  75000 20-12-03
    120401 広島デパート              60000 20-12-04
    120402 福岡電機                 120000 20-12-04
    120403 岡山産業                 210000 20-12-04
    120404 神戸サービス              80000 20-12-04

10行が選択されました。
```

ターゲット側にはデータは入っていない状態です。

```
SQL> select * from uriage;

レコードが選択されませんでした。
```

### 2.CURRENT_DATEを使ったフィルタ設定

CURRENT_DATEで今日の日付を取得できるため、単純に年・月・日がそれぞれ一致するようにフィルタを設定します。

```
YEAR(フィルタ_1.ソース_1.TRAN_DATE)=YEAR(CURRENT_DATE)
and MONTH(フィルタ_1.ソース_1.TRAN_DATE)=MONTH(CURRENT_DATE)
and DAYOFMONTH(フィルタ_1.ソース_1.TRAN_DATE)=DAYOFMONTH(CURRENT_DATE)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694576/7610189d-6764-e684-e84c-651f880795c7.png)

実行してみます。（ちなみに、今日は 2020/12/4 です）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694576/9da31c73-975c-b3ec-0c53-7bc0081c3d19.png)

4件のデータが連携されたことがわかります。

ターゲット側のデータを確認すると、2020/12/4の4件のデータだけが、正しく連携されたことがわかります。

```
SQL> select * from uriage;

   TRAN_NO CUST                    KINGAKU TRAN_DAT
---------- -------------------- ---------- --------
    120401 広島デパート              60000 20-12-04
    120402 福岡電機                 120000 20-12-04
    120403 岡山産業                 210000 20-12-04
    120404 神戸サービス              80000 20-12-04
```

ただ、この CURRENT_DATE は現時点（2020/12）では、UTC時間になっているようです。
午前9時までは前日の日付で処理してもよいような場合は、このまま利用すればよいと思います。

### 3.CURRENT_TIMESTAMPを使ったフィルタ設定

やっぱり、日本時間でないとしっくりこないという場合は、時差の調整が必要になります。
どうやって時差の調整ができるのかと試行錯誤していたら、Data Integrationに CURRENT_TIMESTAMPが準備されていることに気づきました。

日本時間への時差調整の場合は単純に `CURRENT_TIMESTAMP + 9/24`を指定すれば、日本時間で制御できます。

先ほどの例に当てはめると、↓こんな感じです。

```
YEAR(フィルタ_1.URIAGE.TRAN_DATE)=YEAR(CURRENT_TIMESTAMP+9/24)
and MONTH(フィルタ_1.URIAGE.TRAN_DATE)=MONTH(CURRENT_TIMESTAMP+9/24)
and DAYOFMONTH(フィルタ_1.URIAGE.TRAN_DATE)=DAYOFMONTH(CURRENT_TIMESTAMP+9/24)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694576/141cbb5c-2492-06e1-c185-c29fa50ef71f.png)

こちらの設定をすることで、日本時間で制御したり、アプリケーション上の営業日（例えば、朝5時までは前日の売上とするなどの場合）にも対応できそうです。