Oracle Database 23ai：JSON-to-Dualityマイグレータの基本的な使い方（JSONドキュメント・セットのインポート）

# はじめに

Oracle Database 23aiの新機能「JSON Relational Duality（JSONリレーショナル二面性）」を実現するJSON Relational Dualityビューに対して既存のJSONドキュメント・セットをインポートすることを容易にするために、Oracle Database 23aiにはJSON-to-Dualityマイグレータ（DBMS_JSON_DUALITYパッケージ）という便利な機能が用意されています。

JSON-to-Dualityマイグレータが外部表に対応したので、今回は外部表を利用してJSON-to-Dualityマイグレータを使用する検証してみました。

JSON-to-Dualityマイグレータは、以前は通常表（内部表）のみに対応していたため、既存のJSONドキュメント・セットを一度DB内にロードする必要がありましたが、外部表に対応したことにより、既存のドキュメント・セット（JSONデータ）をDBにロードすることなく、既存のJSONドキュメント・セットをJSON Relational Dualityビューに移行できるようになりました。

# 1. 事前準備
検証に使用するJSONドキュメント・セットを準備します。

ディレクトリを作成します。
```
[oracle@db23ai ~]$ mkdir jsondata
```
作成したディレクトリに移動します。
```
cd jsondata
```
以下のJSONファイル（course.json)
を作成します。
```
vi course.json
```

```json:course.json
{
  "courseId" : "MATH101",
  "name" : "Algebra",
  "creditHours" : 3,
  "students" :
  [
    {
      "studentId" : 1,
      "name" : "Donald P."
    },
    {
      "studentId" : 5,
      "name" : "Hye E."
    }
  ],
  "teacher" :
  {
    "teacherId" : 101,
    "name" : "Abdul J."
  },
  "Notes" : "Prerequisite for Advanced Algebra"
}

{
  "courseId" : "MATH102",
  "name" : "Calculus",
  "creditHours" : 4,
  "students" :
  [
    {
      "studentId" : 2,
      "name" : "Elena H."
    },
    {
      "studentId" : 4,
      "name" : "Georgia D."
    },
    {
      "studentId" : 9,
      "name" : "Luis F."
    },
    {
      "studentId" : 10,
      "name" : "Ming L."
    }
  ],
  "teacher" :
  {
    "teacherId" : 101,
    "name" : "Abdul J."
  }
}

{
  "courseId" : "CS101",
  "name" : "Algorithms",
  "creditHours" : 5,
  "students" :
  [
    {
      "studentId" : 1,
      "name" : "Donald P."
    },
    {
      "studentId" : 2,
      "name" : "Elena H."
    },
    {
      "studentId" : 4,
      "name" : "Georgia D."
    },
    {
      "studentId" : 7,
      "name" : "Jatin S."
    },
    {
      "studentId" : 9,
      "name" : "Luis F."
    }
  ],
  "teacher" :
  {
    "teacherId" : 102,
    "name" : "Betty Z."
  }
}

{
  "courseId" : "CS102",
  "name" : "Data Structures",
  "creditHours" : 3,
  "students" :
  [
    {
      "studentId" : 1,
      "name" : "Donald P."
    },
    {
      "studentId" : 2,
      "name" : "Elena H."
    },
    {
      "studentId" : 5,
      "name" : "Hye E."
    },
    {
      "studentId" : 7,
      "name" : "Jatin S."
    },
    {
      "studentId" : 8,
      "name" : "Katie H."
    }
  ],
  "teacher" :
  {
    "teacherId" : 102,
    "name" : "Betty Z."
  }
}

{
  "courseId" : "MATH103",
  "name" : "Advanced Algebra",
  "creditHours" : 3,
  "students" :
  [
    {
      "studentId" : 3,
      "name" : "Francis K."
    },
    {
      "studentId" : 4,
      "name" : "Georgia D."
    },
    {
      "studentId" : 6,
      "name" : "Ileana D."
    },
    {
      "studentId" : 8,
      "name" : "Katie H."
    },
    {
      "studentId" : 9,
      "name" : "Luis F."
    }
  ],
  "teacher" :
  {
    "teacherId" : 103,
    "name" : "Colin J."
  }
}
```

# 2. ディレクトリ・オブジェクトの作成
外部表を作成するために、1.で作成したディレクトリを参照するディレクトリ・オブジェクトを作成します。

SQL*PlusからOracle Database 23aiに接続します。
```
[oracle@db23ai ~]$ sqlplus testuser/Demo#1Demo#1@pdb1

SQL*Plus: Release 23.0.0.0.0 - for Oracle Cloud and Engineered Systems on Thu Mar 27 15:52:29 2025
Version 23.7.0.25.01

Copyright (c) 1982, 2024, Oracle.  All rights reserved.


Connected to:
Oracle Database 23ai EE High Perf Release 23.0.0.0.0 - for Oracle Cloud and Engineered Systems
Version 23.7.0.25.01

SQL> 

```
1.で作成したディレクトリを参照するディレクトリ・オブジェクトを作成します。
```sql
SQL> CREATE DIRECTORY JSON_DATA_DIR AS '/home/oracle/jsondata';

Directory created.

SQL>
```

# 3. 外部表の作成
1.で作成したJSONファイルcourse.jsonに対する外部表course_ext_tblを作成します。

```sql
SQL> CREATE TABLE course_ext_tbl (data JSON)
  2  ORGANIZATION EXTERNAL
  3      ( TYPE ORACLE_BIGDATA
  4        ACCESS PARAMETERS (com.oracle.bigdata.fileformat = jsondoc)
  5        LOCATION          (JSON_DATA_DIR:'course.json')
  6      )
  7  REJECT LIMIT UNLIMITED;

Table created.

SQL>
```

外部表course_ext_tblの内容を確認します。
```sql
SQL> set long 1000
SQL> set pagesize 100
SQL> SELECT * FROM course_ext_tbl;

DATA
--------------------------------------------------------------------------------
{"courseId":"MATH101","name":"Algebra","creditHours":3,"students":[{"studentId":
1,"name":"Donald P."},{"studentId":5,"name":"Hye E."}],"teacher":{"teacherId":10
1,"name":"Abdul J."},"Notes":"Prerequisite for Advanced Algebra"}

{"courseId":"MATH102","name":"Calculus","creditHours":4,"students":[{"studentId"
:2,"name":"Elena H."},{"studentId":4,"name":"Georgia D."},{"studentId":9,"name":
"Luis F."},{"studentId":10,"name":"Ming L."}],"teacher":{"teacherId":101,"name":
"Abdul J."}}

{"courseId":"CS101","name":"Algorithms","creditHours":5,"students":[{"studentId"
:1,"name":"Donald P."},{"studentId":2,"name":"Elena H."},{"studentId":4,"name":"
Georgia D."},{"studentId":7,"name":"Jatin S."},{"studentId":9,"name":"Luis F."}]
,"teacher":{"teacherId":102,"name":"Betty Z."}}

{"courseId":"CS102","name":"Data Structures","creditHours":3,"students":[{"stude
ntId":1,"name":"Donald P."},{"studentId":2,"name":"Elena H."},{"studentId":5,"na
me":"Hye E."},{"studentId":7,"name":"Jatin S."},{"studentId":8,"name":"Katie H."
}],"teacher":{"teacherId":102,"name":"Betty Z."}}

{"courseId":"MATH103","name":"Advanced Algebra","creditHours":"3","students":[{"
studentId":3,"name":"Francis K."},{"studentId":4,"name":"Georgia D."},{"studentI
d":6,"name":"Ileana D."},{"studentId":8,"name":"Katie H."},{"studentId":9,"name"
:"Luis F."}],"teacher":{"teacherId":103,"name":"Colin J."}}


SQL>
````

JSON_SERIALIZEファンクションを使用して、JSONデータを見やすい形式で出力してみます。
```sql
SQL> SELECT JSON_SERIALIZE(data PRETTY) data FROM course_ext_tbl;

DATA
--------------------------------------------------------------------------------
{
  "courseId" : "MATH101",
  "name" : "Algebra",
  "creditHours" : 3,
  "students" :
  [
    {
      "studentId" : 1,
      "name" : "Donald P."
    },
    {
      "studentId" : 5,
      "name" : "Hye E."
    }
  ],
  "teacher" :
  {
    "teacherId" : 101,
    "name" : "Abdul J."
  },
  "Notes" : "Prerequisite for Advanced Algebra"
}

{
  "courseId" : "MATH102",
  "name" : "Calculus",
  "creditHours" : 4,
  "students" :
  [
    {
      "studentId" : 2,
      "name" : "Elena H."
    },
    {
      "studentId" : 4,
      "name" : "Georgia D."
    },
    {
      "studentId" : 9,
      "name" : "Luis F."
    },
    {
      "studentId" : 10,
      "name" : "Ming L."
    }
  ],
  "teacher" :
  {
    "teacherId" : 101,
    "name" : "Abdul J."
  }
}

{
  "courseId" : "CS101",
  "name" : "Algorithms",
  "creditHours" : 5,
  "students" :
  [
    {
      "studentId" : 1,
      "name" : "Donald P."
    },
    {
      "studentId" : 2,
      "name" : "Elena H."
    },
    {
      "studentId" : 4,
      "name" : "Georgia D."
    },
    {
      "studentId" : 7,
      "name" : "Jatin S."
    },
    {
      "studentId" : 9,
      "name" : "Luis F."
    }
  ],
  "teacher" :
  {
    "teacherId" : 102,
    "name" : "Betty Z."
  }
}

{
  "courseId" : "CS102",
  "name" : "Data Structures",
  "creditHours" : 3,
  "students" :
  [
    {
      "studentId" : 1,
      "name" : "Donald P."
    },
    {
      "studentId" : 2,
      "name" : "Elena H."
    },
    {
      "studentId" : 5,
      "name" : "Hye E."
    },
    {
      "studentId" : 7,
      "name" : "Jatin S."
    },
    {
      "studentId" : 8,
      "name" : "Katie H."
    }
  ],
  "teacher" :
  {
    "teacherId" : 102,
    "name" : "Betty Z."
  }
}

{
  "courseId" : "MATH103",
  "name" : "Advanced Algebra",
  "creditHours" : 3,
  "students" :
  [
    {
      "studentId" : 3,
      "name" : "Francis K."
    },
    {
      "studentId" : 4,
      "name" : "Georgia D."
    },
    {
      "studentId" : 6,
      "name" : "Ileana D."
    },
    {
      "studentId" : 8,
      "name" : "Katie H."
    },
    {
      "studentId" : 9,
      "name" : "Luis F."
    }
  ],
  "teacher" :
  {
    "teacherId" : 103,
    "name" : "Colin J."
  }
}


5 rows selected.

SQL>
```

JSONファイルcourse.jsonの内容が表示されていることが確認できました。

# 4.JSON-to-Dualityコンバータの実行

JSON-to-Dualityコンバータ（DBMS_JSON_DUALITY.INFER_AND_GENERATE_SCHEMAファンクション）を使用して、3.で作成した外部表course_ext_tbl内のJSONドキュメント・セットをもとにしてJSON Relational Dualityビューおよびそのベースとなるスキーマ・オブジェクトを作成するDDLを取得します。

DBMS_JSON_DUALITY.INFER_AND_GENERATE_SCHEMAファンクションを実行する際のパラメータとして、
tableNames：JSONドキュメント・セットを格納する表の名前（ここではcourse_ext_tbl）
viewNames：作成するJSON Relational Dualityビューの名前（ここではcourse）
を指定します。

```sql
SQL> set feedback on
SQL> set serveroutput on
SQL> 
SQL> DECLARE
  2  	 json_dv_sql CLOB;
  3  BEGIN
  4  	 json_dv_sql :=
  5  	     DBMS_JSON_DUALITY.INFER_AND_GENERATE_SCHEMA(
  6  		 JSON('{"tableNames":["COURSE_EXT_TBL"],
  7                 "viewNames" :["COURSE"],
  8                 "useFlexFields" : FALSE}')
  9  	     );
 10  
 11  	 DBMS_OUTPUT.PUT_LINE('DDL Script: ');
 12  	 DBMS_OUTPUT.PUT_LINE(json_dv_sql);
 13  END;
 14  /
DDL Script:
BEGIN 
EXECUTE IMMEDIATE 'CREATE TABLE course_teacher(
   name  varchar2(64)  /*
UNIQUE */,
   teacher_id  number  GENERATED BY DEFAULT ON NULL AS IDENTITY,

PRIMARY KEY(teacher_id)
)';

EXECUTE IMMEDIATE 'CREATE TABLE course_students(

name  varchar2(64)  /* UNIQUE */,
   student_id  number  GENERATED BY DEFAULT ON
NULL AS IDENTITY,
   course_id_course_root  varchar2(64),
   PRIMARY
KEY(student_id)
)';

EXECUTE IMMEDIATE 'CREATE TABLE course_root(
   name
varchar2(64)  /* UNIQUE */,
   notes  varchar2(64)	/* UNIQUE */,
   course_id
varchar2(64)  DEFAULT ON NULL SYS_GUID(),
   credit_hours  number  /* UNIQUE
*/,
   teacher_id_course_teacher  number,
   PRIMARY KEY(course_id)
)';

EXECUTE
IMMEDIATE 'ALTER TABLE course_students
ADD CONSTRAINT
fk_course_students_to_course_root FOREIGN KEY (course_id_course_root) REFERENCES
course_root(course_id) DEFERRABLE';
EXECUTE IMMEDIATE 'ALTER TABLE
course_root
ADD CONSTRAINT fk_course_root_to_course_teacher FOREIGN KEY
(teacher_id_course_teacher) REFERENCES course_teacher(teacher_id)
DEFERRABLE';
EXECUTE IMMEDIATE 'CREATE INDEX IF NOT EXISTS
fk_course_students_to_course_root_index ON
course_students(course_id_course_root)';
EXECUTE IMMEDIATE 'CREATE INDEX IF NOT
EXISTS fk_course_root_to_course_teacher_index ON
course_root(teacher_id_course_teacher)';

EXECUTE IMMEDIATE 'CREATE OR REPLACE
JSON RELATIONAL DUALITY VIEW COURSE AS 
course_root @insert @update @delete
{ 

_id : course_id
  name
  Notes: notes
  teacher: course_teacher @insert @update
@object
  { 
    name
    teacherId: teacher_id
  } 
  courseId @generated
(path: "$._id")
  students: course_students @insert @update @delete @array
  {

name
    studentId: student_id
  } 
  creditHours: credit_hours
}'; 

EXECUTE
IMMEDIATE 'CREATE OR REPLACE TRIGGER INSERT_TRIGGER_COURSE
  BEFORE INSERT
  ON
COURSE
  FOR EACH ROW
DECLARE 
  inp_jsonobj json_object_t;
BEGIN
  inp_jsonobj
:= json_object_t(:new.data);
  IF NOT inp_jsonobj.has(''_id'') 
  THEN 

inp_jsonobj.put(''_id'', inp_jsonobj.get(''courseId''));
    :new.data :=
inp_jsonobj.to_json;
  END IF;
END;'; 
END;


PL/SQL procedure successfully completed.

SQL> 
```
JSON Relational Dualityビューcourseおよびそのベースとなる以下のスキーマ・オブジェクトを作成するDDLが取得できました。

＜表＞
・course_teacher
・course_students
・course_root

＜参照整合性制約＞
・fk_course_students_to_course_root
・fk_course_root_to_course_teacher

＜インデックス＞
・fk_course_students_to_course_root_index
・fk_course_root_to_course_teacher_index

＜トリガー＞
・INSERT_TRIGGER_COURSE

今回は、DBMS_JSON_DUALITY.INFER_AND_GENERATE_SCHEMAファンクションで生成されたDDLをそのまま実行してみます。
```sql
SQL> DECLARE
  2  	 json_dv_sql CLOB;
  3  BEGIN
  4  	 json_dv_sql :=
  5  	     DBMS_JSON_DUALITY.INFER_AND_GENERATE_SCHEMA(
  6  		 JSON('{"tableNames":["COURSE_EXT_TBL"],
  7                 "viewNames" :["COURSE"],
  8                 "useFlexFields" : FALSE}')
  9  	     );
 10  
 11  	 EXECUTE IMMEDIATE json_dv_sql;
 12  END;
 13  /

PL/SQL procedure successfully completed.

SQL>
```

作成された表を確認してみます。
```sql
SQL> col table_name for a20
SQL> SELECT table_name, external FROM user_tables;

TABLE_NAME	         EXT
-------------------- ---
COURSE_EXT_TBL	     YES
COURSE_TEACHER	     NO
COURSE_STUDENTS      NO
COURSE_ROOT	         NO

4 rows selected.

SQL>
```

COURSE_TEACHER、COURSE_STUDENTS、COURSE_ROOTの3つの表が作成されたことが確認できました。

各表の構造を確認してみます。

course_root表の構造を確認します。
```
SQL> desc course_root
 Name					                   Null?    Type
 ----------------------------------------- -------- ----------------------------
 NAME						                        VARCHAR2(64)
 NOTES						                        VARCHAR2(64)
 COURSE_ID				                   NOT NULL VARCHAR2(64)
 CREDIT_HOURS					                    NUMBER
 TEACHER_ID_COURSE_TEACHER			                NUMBER

SQL> 
```

course_teacher表の構造を確認します。
```
SQL> desc course_teacher
 Name					                   Null?    Type
 ----------------------------------------- -------- ----------------------------
 NAME						                        VARCHAR2(64)
 TEACHER_ID				                   NOT NULL NUMBER

SQL>
```

course_students表の構造を確認します。
```
SQL> desc course_students
 Name					                   Null?    Type
 ----------------------------------------- -------- ----------------------------
 NAME						                        VARCHAR2(64)
 STUDENT_ID				                   NOT NULL NUMBER
 COURSE_ID_COURSE_ROOT				                VARCHAR2(64)

SQL>
```

作成されたJSON Relational Dualityビューを確認してみます。
```sql
SQL> col view_name for a20
SQL> SELECT view_name, duality_view FROM user_views;

VIEW_NAME	         DUA
-------------------- ---
COURSE		         YES

1 row selected.

SQL>
```

JSON Relational Dualityビューcourseが作成されたことが確認できました。

JSON Relational Dualityビューcourseの構造を確認してみます。
```
SQL> desc course
 Name					                   Null?    Type
 ----------------------------------------- -------- ----------------------------
 DATA						                        JSON

SQL>
```

JSON型の列dataのみを持つことが確認できました。

以上で、JSON-to-Dualityコンバータの動作が確認できました。

# 5.JSON-to-Dualityインポータの実行

JSON Relational Dualityビューcourseおよびそのベースとなる以下のスキーマ・オブジェクトが作成できたので、JSON-to-Dualityインポータ（DBMS_JSON_DUALITY.IMPORTプロシージャ）を使用して、JSONドキュメント・セットをJSON Relational Dualityビューcourseにインポートします。
（実際には、JSON Relational Dualityビューcourseのベースとなっている各表にデータがインポートされます。）

DBMS_JSON_DUALITY.IMPORTプロシージャを実行する際のパラメータとして、
table_name：JSONドキュメント・セットを格納する表の名前（ここではcourse_ext_tbl）
view_name：JSONドキュメント・セットのインポート先となるJSON Relational Dualityビューの名前（ここではcourse）
err_log_name:エラー・ログを出力する表の名前（ここではcourse_err_log）
を指定します。

```sql
SQL> BEGIN
  2      DBMS_JSON_DUALITY.IMPORT(
  3          table_name   => 'COURSE_EXT_TBL',
  4          view_name    => 'COURSE',
  5          err_log_name => 'COURSE_ERR_LOG'
  6      );
  7  END;
  8  /

PL/SQL procedure successfully completed.

SQL> 
```

プロシージャが正常に実行できたので、JSON Relational Dualityビューcourseの内容を確認してみます
```sql
SQL> set long 1000
SQL> SELECT * FROM course;

DATA
--------------------------------------------------------------------------------
{"_id":"MATH101","_metadata":{"etag":"83169CAA6AD91D83C297192FCBB7D0FF","asof":"
00000000010781AC"},"name":"Algebra","Notes":"Prerequisite for Advanced Algebra",
"teacher":{"name":"Abdul J.","teacherId":101},"students":[],"creditHours":3,"cou
rseId":"MATH101"}

{"_id":"MATH102","_metadata":{"etag":"5E4BF038FD989301DDED31EE0BE6229D","asof":"
00000000010781AC"},"name":"Calculus","Notes":null,"teacher":{"name":"Abdul J.","
teacherId":101},"students":[{"name":"Ming L.","studentId":10}],"creditHours":4,"
courseId":"MATH102"}

{"_id":"CS101","_metadata":{"etag":"50B0DF59D0C4E00A7AC1415FDE913AC0","asof":"00
000000010781AC"},"name":"Algorithms","Notes":null,"teacher":{"name":"Betty Z.","
teacherId":102},"students":[],"creditHours":5,"courseId":"CS101"}

{"_id":"CS102","_metadata":{"etag":"7140A57E3692246912F90586A38014EB","asof":"00
000000010781AC"},"name":"Data Structures","Notes":null,"teacher":{"name":"Betty
Z.","teacherId":102},"students":[{"name":"Donald P.","studentId":1},{"name":"Ele
na H.","studentId":2},{"name":"Hye E.","studentId":5},{"name":"Jatin S.","studen
tId":7}],"creditHours":3,"courseId":"CS102"}

{"_id":"MATH103","_metadata":{"etag":"5EA16B170A05B2D151DCA39A7315375B","asof":"
00000000010781AC"},"name":"Advanced Algebra","Notes":null,"teacher":{"name":"Col
in J.","teacherId":103},"students":[{"name":"Francis K.","studentId":3},{"name":
"Georgia D.","studentId":4},{"name":"Ileana D.","studentId":6},{"name":"Katie H.
","studentId":8},{"name":"Luis F.","studentId":9}],"creditHours":3,"courseId":"M
ATH103"}


5 rows selected.

SQL>
```

JSON_SERIALIZEファンクションを使用して、JSONデータを見やすい形式で出力してみます。
```sql
SQL> SELECT JSON_SERIALIZE(data PRETTY) data FROM course;

DATA
--------------------------------------------------------------------------------
{
  "_id" : "MATH101",
  "_metadata" :
  {
    "etag" : "83169CAA6AD91D83C297192FCBB7D0FF",
    "asof" : "000000000107823C"
  },
  "name" : "Algebra",
  "Notes" : "Prerequisite for Advanced Algebra",
  "teacher" :
  {
    "name" : "Abdul J.",
    "teacherId" : 101
  },
  "students" :
  [
  ],
  "creditHours" : 3,
  "courseId" : "MATH101"
}

{
  "_id" : "MATH102",
  "_metadata" :
  {
    "etag" : "5E4BF038FD989301DDED31EE0BE6229D",
    "asof" : "000000000107823C"
  },
  "name" : "Calculus",
  "Notes" : null,
  "teacher" :
  {
    "name" : "Abdul J.",
    "teacherId" : 101
  },
  "students" :
  [
    {
      "name" : "Ming L.",
      "studentId" : 10
    }
  ],
  "creditHours" : 4,
  "courseId" : "MATH102"
}

{
  "_id" : "CS101",
  "_metadata" :
  {
    "etag" : "50B0DF59D0C4E00A7AC1415FDE913AC0",
    "asof" : "000000000107823C"
  },
  "name" : "Algorithms",
  "Notes" : null,
  "teacher" :
  {
    "name" : "Betty Z.",
    "teacherId" : 102
  },
  "students" :
  [
  ],
  "creditHours" : 5,
  "courseId" : "CS101"
}

{
  "_id" : "CS102",
  "_metadata" :
  {
    "etag" : "7140A57E3692246912F90586A38014EB",
    "asof" : "000000000107823C"
  },
  "name" : "Data Structures",
  "Notes" : null,
  "teacher" :
  {
    "name" : "Betty Z.",
    "teacherId" : 102
  },
  "students" :
  [
    {
      "name" : "Donald P.",
      "studentId" : 1
    },
    {
      "name" : "Elena H.",
      "studentId" : 2
    },
    {
      "name" : "Hye E.",
      "studentId" : 5
    },
    {
      "name" : "Jatin S.",
      "studentId" : 7
    }
  ],
  "creditHours" : 3,
  "courseId" : "CS102"
}

{
  "_id" : "MATH103",
  "_metadata" :
  {
    "etag" : "5EA16B170A05B2D151DCA39A7315375B",
    "asof" : "000000000107823C"
  },
  "name" : "Advanced Algebra",
  "Notes" : null,
  "teacher" :
  {
    "name" : "Colin J.",
    "teacherId" : 103
  },
  "students" :
  [
    {
      "name" : "Francis K.",
      "studentId" : 3
    },
    {
      "name" : "Georgia D.",
      "studentId" : 4
    },
    {
      "name" : "Ileana D.",
      "studentId" : 6
    },
    {
      "name" : "Katie H.",
      "studentId" : 8
    },
    {
      "name" : "Luis F.",
      "studentId" : 9
    }
  ],
  "creditHours" : 3,
  "courseId" : "MATH103"
}


5 rows selected.

SQL> 
```

インポート元のJSONドキュメント・ドキュメントセット内のJSONドキュメントが正しくインポートされていることが確認できました。
ただし、各JSONドキュメントには以下の要素が追加されています。
・_id（ドキュメント識別子）
・_metadata（値ベースの同時実行性制御のための"etag"とデータベースのSCNを表す"asof"を含む）

JSON Relational Dualityビューcourseのベースとなっている各表の内容を確認してみます。

course_root表の内容を確認してみます。
```sql
SQL> col name for a20
SQL> col notes for a35
SQL> col course_id for a10
SQL> set linesize 120
SQL> SELECT * FROM course_root;

NAME		         NOTES				                 COURSE_ID  CREDIT_HOURS TEACHER_ID_COURSE_TEACHER
-------------------- ----------------------------------- ---------- ------------ -------------------------
Algebra 	         Prerequisite for Advanced Algebra	 MATH101	           3		                101
Calculus						                         MATH102	           4		                101
Algorithms						                         CS101		           5		                102
Data Structures 					                     CS102		           3		                102
Advanced Algebra					                     MATH103	           3		                103

5 rows selected.

SQL>
```

course_teacher表の内容を確認してみます。
```sql
SQL> SELECT * FROM course_teacher;

NAME		         TEACHER_ID
-------------------- ----------
Abdul J.		            101
Betty Z.		            102
Colin J.		            103

3 rows selected.

SQL>
```

course_students表の内容を確認してみます。
```sql
SQL> SELECT * FROM course_students;

NAME		         STUDENT_ID COURSE_ID_COURSE_ROOT
-------------------- ---------- ----------------------------------------------------------------
Donald P.		              1 CS102
Hye E.			              5 CS102
Elena H.		              2 CS102
Georgia D.		              4 MATH103
Luis F. 		              9 MATH103
Ming L. 		             10 MATH102
Jatin S.		              7 CS102
Katie H.		              8 MATH103
Francis K.		              3 MATH103
Ileana D.		              6 MATH103

10 rows selected.

SQL>
```

インポート元のJSONドキュメント・ドキュメントセット内のJSONドキュメントが、JSON Relational Dualityビューcourseのベースとなっている各表に正しくインポートされていることが確認できました。

# 参考情報
・[DBMS_JSON_DUALITY.INFER_AND_GENERATE_SCHEMAファンクション](https://docs.oracle.com/cd/G11854_01/arpls/dbms_json_duality.html#GUID-96A451DC-42F6-4472-8FA2-EA0C70FDC360)
・[DBMS_JSON_DUALITY.IMPORTプロシージャ](https://docs.oracle.com/cd/G11854_01/arpls/dbms_json_duality.html#GUID-F05A7FB5-FC79-4098-A674-AF5F6142BBA1)
・[Loading External JSON Data](https://docs.oracle.com/en/database/oracle/oracle-database/23/adjsn/loading-external-json-data.html#GUID-52EFC452-5E65-4148-8070-1FA588A6E697__CACJJGAD)
・[JSON_SERIALIZEファンクション](https://docs.oracle.com/cd/G11854_01/adjsn/json-data-type.html#GUID-667D37FF-F5FB-465D-B8AE-DAE88F191B2F)