21.12 コンバータの使用(useFlexFields=false)
useFlexFields
= false
を指定したJSON-to-Dualityコンバータの使用を示します。それ以外は、構成はデフォルトです(minFieldFrequency
およびminTypeFrequency
を除く)。ドキュメント・セットをサポートするために必要なデータベース・オブジェクトが推測され、それらを構築するためのSQL DDLコードが生成されます。
false
値のuseFlexFields
をDBMS_JSON_DUALITY.infer_schema
に渡します。それ以外は、このコールは「コンバータの使用(デフォルトの動作)」の例「INFER_SCHEMAおよびGENERATE_SCHEMA (useFlexFields = true)」と同じです。また、infer_schema
によって返されるJSONスキーマは、useFlexFields
がtrue
の場合でもfalse
の場合でも同じです。
DBMS_JSON_DUALITY.generate_schema
のコールも同じです。生成されるDDLコードの違いは、次の点のみです:
-
useFlexFields
がfalse
の場合、二面性ビューの基礎となる表にはフレックス列がありません。 -
useFlexFields
がfalse
の場合、二面性ビューはフレックス列を参照しません。
例21-31 GENERATE_SCHEMAからのDDLコード(useFlexFields = false)
ファンクションDBMS_JSON_DUALITY.generate_schema
は、useFlexFields
= false
でファンクションinfer_schema
によって生成されたJSONスキーマが渡された場合、ここに示す生成されたDDLコードを生成します。
このDDLコードと、useFlexFields
= true
で生成されたコードとの違いは、ここでは基礎となる表にフレックス列がなく、二面性ビューのフレックス列への参照がないことのみです。
BEGIN
EXECUTE IMMEDIATE 'CREATE TABLE student_dormitory(
dorm_id number GENERATED BY DEFAULT ON NULL AS IDENTITY,
dorm_name varchar2(64),
PRIMARY KEY(dorm_id)
)';
EXECUTE IMMEDIATE 'CREATE TABLE map_course_root_to_student_root(
map_course_id varchar2(64) DEFAULT ON NULL SYS_GUID(),
map_student_id number GENERATED BY DEFAULT ON NULL AS IDENTITY,
PRIMARY KEY(map_course_id,map_student_id)
)';
EXECUTE IMMEDIATE 'CREATE TABLE student_root(
age number,
name varchar2(64),
dorm_id number,
advisor_id number,
student_id number GENERATED BY DEFAULT ON NULL AS IDENTITY,
PRIMARY KEY(student_id)
)';
EXECUTE IMMEDIATE 'CREATE TABLE teacher_root(
"_id" number GENERATED BY DEFAULT ON NULL AS IDENTITY,
name varchar2(64),
salary number,
department varchar2(64),
phone_number json VALIDATE ''{"oneOf" : [{ "type" :"string"},
{ "type" :"array"}]}'',
PRIMARY KEY("_id")
)';
EXECUTE IMMEDIATE 'CREATE TABLE course_root(
name varchar2(64),
avg_grade json VALIDATE ''{"oneOf" : [{ "type" :"number"},
{ "type" :"string"}]}'',
course_id varchar2(64) DEFAULT ON NULL SYS_GUID(),
class_type varchar2(64),
credit_hours json VALIDATE ''{"oneOf" : [{ "type" :"number"},
{ "type" :"string"}]}'',
"_id_teacher_root" number,
PRIMARY KEY(course_id)
)';
EXECUTE IMMEDIATE 'ALTER TABLE map_course_root_to_student_root
ADD CONSTRAINT fk_map_course_root_to_student_root_to_course_root FOREIGN KEY (map_course_id) REFERENCES course_root(course_id) DEFERRABLE';
EXECUTE IMMEDIATE 'ALTER TABLE map_course_root_to_student_root
ADD CONSTRAINT fk_map_course_root_to_student_root_to_student_root FOREIGN KEY (map_student_id) REFERENCES student_root(student_id) DEFERRABLE';
EXECUTE IMMEDIATE 'ALTER TABLE student_root
ADD CONSTRAINT fk_student_root_to_student_dormitory FOREIGN KEY (dorm_id) REFERENCES student_dormitory(dorm_id) DEFERRABLE';
EXECUTE IMMEDIATE 'ALTER TABLE student_root
ADD CONSTRAINT fk_student_root_to_teacher_root FOREIGN KEY (advisor_id) REFERENCES teacher_root("_id") DEFERRABLE';
EXECUTE IMMEDIATE 'ALTER TABLE course_root
ADD CONSTRAINT fk_course_root_to_teacher_root FOREIGN KEY ("_id_teacher_root") REFERENCES teacher_root("_id") DEFERRABLE';
EXECUTE IMMEDIATE 'CREATE INDEX IF NOT EXISTS fk_map_course_root_to_student_root_to_course_root_index ON map_course_root_to_student_root(map_course_id)';
EXECUTE IMMEDIATE 'CREATE INDEX IF NOT EXISTS fk_map_course_root_to_student_root_to_student_root_index ON map_course_root_to_student_root(map_student_id)';
EXECUTE IMMEDIATE 'CREATE INDEX IF NOT EXISTS fk_student_root_to_student_dormitory_index ON student_root(dorm_id)';
EXECUTE IMMEDIATE 'CREATE INDEX IF NOT EXISTS fk_student_root_to_teacher_root_index ON student_root(advisor_id)';
EXECUTE IMMEDIATE 'CREATE INDEX IF NOT EXISTS fk_course_root_to_teacher_root_index ON course_root("_id_teacher_root")';
EXECUTE IMMEDIATE 'CREATE OR REPLACE JSON RELATIONAL DUALITY VIEW STUDENT AS
student_root @insert @update @delete
{
_id : student_id
age
name
courses: map_course_root_to_student_root @insert @update @delete @array
{
ora$mapCourseId: map_course_id
ora$mapStudentId: map_student_id
course_root @unnest @insert @update @object
{
name
avgGrade: avg_grade
courseNumber: course_id
}
}
advisorId:advisor_id
dormitory: student_dormitory @insert @update @object
{
dormId: dorm_id
dormName: dorm_name
}
studentId @generated (path: "$._id")
}';
EXECUTE IMMEDIATE 'CREATE OR REPLACE JSON RELATIONAL DUALITY VIEW TEACHER AS
teacher_root @insert @update @delete
{
"_id"
name
salary
department
phoneNumber: phone_number
coursesTaught: course_root @insert @update @delete @array
{
name
courseId: course_id
classType: class_type
}
studentsAdvised: student_root @insert @update @delete @array
{
name
dormId:dorm_id
studentId: student_id
}
}';
EXECUTE IMMEDIATE 'CREATE OR REPLACE JSON RELATIONAL DUALITY VIEW COURSE AS
course_root @insert @update @delete
{
_id : course_id
name
teacher: teacher_root @insert @update @object
{
name
teacherId: "_id"
}
courseId @generated (path: "$._id")
students: map_course_root_to_student_root @insert @update @delete @array
{
ora$mapCourseId: map_course_id
ora$mapStudentId: map_student_id
student_root @unnest @insert @update @object
{
name
studentId: student_id
}
}
creditHours: credit_hours
}';
EXECUTE IMMEDIATE 'CREATE OR REPLACE TRIGGER INSERT_TRIGGER_STUDENT
BEFORE INSERT
ON STUDENT
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(''studentId''));
:new.data := inp_jsonobj.to_json;
END IF;
END;';
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;
次の例「VALIDATE_SCHEMA_REPORT (useFlexFields = false)」は、まれなフィールドNotes
がコースのドキュメント・セットの外れ値であることを示しています。
コンバータによって作成されたフレックス列がない場合、コンバータによってマップされていないフィールド(単純なSQLスカラー列に格納できないフィールドなど)のインポート時にエラーがログに記録されます。useFlexFields
がtrue
(デフォルト値)のとき、マップされていないフィールドNotes
は、フレックス・フィールドに格納されることで、コースのドキュメントに保持されます。ただし、useFlexFields
がfalse
の場合、フィールドNotes
はインポート時にエラーとしてログに記録されます。
DDLコードを生成してから実行すると、二面性ビューとその基礎となる表が作成されます。
DDLコードの実行後、入力表および二面性ビューの各種類(学生、教師、コース)に対してコンバータ・ファンクションDBMS_JSON_DUALITY.validate_schema_report
を実行して、変換を検証します。
例21-32 VALIDATE_SCHEMA_REPORT (useFlexFields = false)
このコードは、「コンバータの使用(デフォルトの動作)」の例「VALIDATE_SCHEMA_REPORT (デフォルト・ケース(useFlexFields = true))」と同じです。
SELECT * FROM DBMS_JSON_DUALITY.validate_schema_report(
table_name => 'STUDENT_TAB',
view_name => 'STUDENT');
SELECT * FROM DBMS_JSON_DUALITY.validate_schema_report(
table_name => 'TEACHER_TAB',
view_name => 'TEACHER');
SELECT * FROM DBMS_JSON_DUALITY.validate_schema_report(
table_name => 'COURSE_TAB',
view_name => 'COURSE');
学生の表およびビューに関してレポートされるエラーは、「コンバータの使用(デフォルトの動作)」の例「VALIDATE_SCHEMA_REPORT (デフォルト・ケース(useFlexFields = true))」と同じです。(つまり、フィールドage
が文字列値"Nineteen"
)。
教師の表およびビューに関するエラーはレポートされません(useFlexFields
= true
の場合と同様)。
ただし、コースの表およびビューに関するエラーが(useFlexFields
= true
の場合と同様に)レポートされないかわりに、useFlexFields
= false
の場合、フィールド出現の外れ値フィールドNotes
に関するエラーがレポートされます。これは、デフォルトの場合、そのフィールドがフレックス列に格納されるためです。
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"}
ERRORS
------
[{"schemaPath":"$","instancePath":"$","code":"JZN-00501","error":"JSON schema va
lidation failed"},{"schemaPath":"$.additionalProperties","instancePath":"$","cod
e":"JZN-00518","error":"invalid additional properties: 'Notes'"},{"schemaPath":
"$.additionalProperties","instancePath":"$.Notes","code":"JZN-00502","error":"JS
ON boolean schema was false"}]
useFlexFields
= true
の場合と同様に、インポートの前に、Luis Jの学生の入力ドキュメントのage
フィールドを変更して、文字列値"Nineteen"
ではなく数値19
を指定できます。また、データからフィールドNotes
を削除することも、含めることができるようにminTypeFrequency
の値を緩和(低く)することもできます。
-
サブプログラム
generate_schema、infer_schema
およびvalidate_import_report
の詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「DBMS_JSON_DUALITY」を参照してください -
ファンクション
DBMS_JSON_SCHEMA.validate_report
の詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』の「VALIDATE_REPORTファンクション」を参照してください
親トピック: JSONから二面性への移行