6 JSONスキーマ

JSON文書の構造と型情報を検証するために、JSONスキーマを作成できます。データは、スキーマ妥当なデータのみがJSON列に挿入されるように、その場で検証することも、チェック制約を使用して検証することもできます。

ほとんどのJSONデータの使用は、スキーマレスです。JSONデータを使用するアプリケーションは、変更の要件にすばやく対応できます。アプリケーションは、それが使用している記憶域スキーマを変更することなく変更および再デプロイできます。

ただし、JSONデータの一部をスキーマに準拠させることが必要になる場合があります。特定の列に格納されるすべてのデータがスキーマで定義された構造になっていることを確認することも、このような構造が特定のJSON文書にあるかどうかを確認してから処理することもできます。

JSONスキーマは、Request For Comments (RFC)ドラフトであるJSONスキーマ標準を尊重するJSON文書です。

JSONスキーマを使用して、他のJSON文書を記述または検証できます。json-schema.orgを参照してください。JSONスキーマでは、妥当とみなされるJSONデータの構造と許可される値のを指定します。「妥当性」は、常に特定のスキーマに関するものです。(その一方で、「整形式の性質」は単に構文的に正しいことを意味します)。

Oracle DatabaseでサポートされているJSONスキーマは、自己完結型です。別のJSONスキーマを含めることもインポートすることもできません。(そうしようとすると、そのために使用するスキーマ・キーワードは、ユーザー定義のキーワードであるかのように単に無視されます。)ただし、適切に定義されたアプリケーション使用方法ドメインをJSONスキーマとして使用できます。また、ドメインは別のドメインのエクスポートおよびインポートが可能です。(依存関係の追跡と進化も可能になります)。

これは、標準フィールド(キーワード)のみを使用する単純なJSONスキーマの例です。

{"type"       : "object",
 "properties" : {"firstName" : {"type"      : "string",
                                "minLength" : 1},
                 "salary"    : {"type"      : "number",
                                "minimum"   : 10000}},
 "required"   : ["firstName"]} 

妥当な文書が、フィールドfirstNameおよびオプションのフィールドsalaryを持つJSONオブジェクトであることを指定します。このオブジェクトには、1文字以上の文字列であることが必要な必須のfirstNameフィールドと、オプションであるが存在する場合は10,000以上の数値であることが必要なsalaryフィールドとは別に、追加のフィールドを含めることができます。

関連項目:

6.1 JSONスキーマを使用したJSON文書の検証

JSONスキーマでは通常、他のJSON文書の許可された構造およびデータ型(そのスキーマに関する妥当性)を指定しますそのため、JSONスキーマの通常の用途は、JSONデータを検証することになります。

JSONデータは、JSONスキーマに対して次のいずれかの方法で検証できます。

  • 条件is JSON (またはis not JSON)を使用し、キーワードVALIDATEとJSONスキーマの名前を指定して、対象となるデータがそのスキーマに対して有効(または無効)であるかどうかをテストします。スキーマは、リテラル文字列またはアプリケーション使用方法ドメインとして指定できます。キーワードVALIDATEの後にはオプションでキーワードUSINGを指定することもできます。

    条件is jsonVALIDATEは、その条件が使用可能な任意の場所で使用できます。これには、WHERE句での使用やチェック制約としての使用が含まれ、それにより有効なデータのみが列に挿入されるようにします。例6-1に、WHERE句でのその使用方法を示します。

    JSON型の列のチェック制約として使用する場合は、is jsonを省略して、キーワードVALIDATEのみを直接使用することもできます。JSON型の列の場合、次の2つの表作成は同等です。

    CREATE TABLE tab (jcol JSON VALIDATE '{"type" : "object"}');
    CREATE TABLE tab (jcol JSON CONSTRAINT jchk
      CHECK (jcol IS JSON VALIDATE '{"type" : "object"}'));

    VALIDATEを条件is JSONとともに使用する場合、JSONスキーマで、挿入するデータ内のフィールドが日付などのOracle固有のJSON言語スカラー型のextendedType要件を満たす必要があると指定されている場合、デフォルトでは、その型ではないスカラー値によって、必要な型に対して値が型キャストできる場合でも挿入が失敗します。

    ただし、VALIDATEをキーワードCASTと一緒に使用すると、可能であればそのような型キャストが実行されます。たとえば、サポートされているISO 8601日時形式の入力文字列は、JSON言語の日付スカラー値に自動的にキャストできます。拡張スカラー値への型キャストを使用したJSONスキーマ検証を参照してください。

  • JSON型データのチェック制約としてドメインを使用します。次に例を示します。

    CREATE DOMAIN jd AS JSON CONSTRAINT jchkd
      CHECK (jd IS JSON VALIDATE '{"type" : "object"}');
    CREATE TABLE jtab(jcol JSON DOMAIN jd);

    スキーマからドメインを作成するときには、制約とis jsonを省略して、キーワードVALIDATEのみを使用することもできます。このドメイン作成は、前のものと同等です。

    CREATE DOMAIN jd AS JSON VALIDATE '{"type" : "object"}';
  • パッケージDBMS_JSON_SCHEMAに含まれているPL/SQLファンクションまたはプロシージャis_validを使用します。このファンクションは、SQL問合せで使用できます。データが有効な場合は1、無効な場合は0が返されます。プロシージャは、有効か無効かを示すOUTパラメータと、妥当性(trueまたはfalse)および不当性の理由についての完全な情報を提供するJSONオブジェクトを返す別のOUTパラメータを返します。

    たとえば、このプロシージャを使用すると、スキーマmyschema (JSON)に対してデータmyjson (JSON)がチェックされ、パラメータvalidity (BOOLEAN)およびerrors (JSON)に出力されます。

    DBMS_JSON_SCHEMA.is_valid(myjson, myschema, validity, errors);
  • プロシージャ(関数ではない)is_validを使用する場合、OUTパラメータとして検証エラー・レポートにアクセスできます。関数is_validを使用する場合、このようなレポートにアクセスできません。関数is_validを使用するかわりにSQL問合せでPL/SQLファンクションDBMS_JSON_SCHEMA.validate_reportを使用して、プロシージャis_validOUTパラメータで提供されるものと同じ完全な検証情報を検証して、JSON型のインスタンスとして返すことができます。この関数が入力として受け入れるJSONデータは、データ型JSONまたはVARCHAR2 (CLOBまたはBLOBではない)のいずれかになります。

    たとえば、この問合せは、2番目の引数であるJSONスキーマに対して最初の引数であるテキストJSON文書の検証を試み、検証レポートをmyreportとして返します。

    
    SELECT DBMS_JSON_SCHEMA.validate_report('{"name" : "scott",
                                              "role" : "developer"}',
                                            '{"type" : "array"}')
      AS myreport;
  • PL/SQL JSON_ELEMENT_Tのブール・メソッドschema_validate()を使用します。これは、JSONVARCHAR2またはJSON_ELEMENT_T型の引数としてJSONスキーマを受け入れます。

    たとえば、dJSON_ELEMENT_T型のPL/SQLインスタンスの場合、このコードは、引数として渡されたJSONスキーマに対してJSONデータdが有効(TRUE)か無効(FALSE)かを示すBOOLEAN値を返します。つまり、データがJSONオブジェクトかどうかをチェックします。

    isvalid := d.schema_validate('{"type" : "object"}');

JSONスキーマ自体がJSONスキーマとして定義されます。このスキーマは、JSONスキーマ標準で許可されたものを妥当なJSONスキーマとして定義します。つまり、どのような形式のJSON文書がJSONスキーマであるかを定義することになります。PL/SQLファンクションDBMS_JSON_SCHEMA.is_schema_validを使用すると、JSONスキーマを検証できます。つまり、JSONスキーマ定義スキーマに対して検証するということです。

静的ディクショナリ・ビューDBA_JSON_SCHEMA_COLUMNSALL_JSON_SCHEMA_COLUMNSおよびUSER_JSON_SCHEMA_COLUMNSでは、チェック制約として使用できるJSONスキーマが示されます。

これらのビューの各行には、表の名前、JSON列、JSONスキーマによって定義された制約、JSONスキーマ自体、およびJSONスキーマに対してキャスト・モードが指定されているかどうかが示されます。ビューDBA_JSON_SCHEMA_COLUMNSおよびALL_JSON_SCHEMA_COLUMNSには、表所有者の名前も含まれています。

例6-1 条件IS JSONでのJSONスキーマに対するJSONデータの検証

この問合せでは、示されているリテラルJSONスキーマに対して検証するデータのみが選択されています。ここでは、フィールドPONumberの数値が0以上である必要があります。

これは、列j_purchaseorderがスキーマ検証チェック制約なしで作成された場合でも機能します。

SELECT po_document
  FROM j_purchaseorder
  WHERE po_document IS JSON VALIDATE
    '{"type"       : "object",
      "properties" : {"PONumber": {"type"    : "number",
                                   "minimum" : 0}}}'

関連項目:

6.2 拡張スカラー値への型キャストを使用したJSONスキーマ検証

JSON型列のIS JSONチェック制約でVALIDATE CASTを使用する場合、JSONスキーマに対応するために、挿入するデータをOracle固有のJSON言語スカラー値に自動的に型キャストできます。たとえば、ISO 8601日付文字列をJSON日付値に変換できます。

JSONスキーマで、挿入するデータ内のフィールドが特定のOracle固有スカラー型のextendedType要件を満たす必要があると指定されている場合、デフォルトでは、その型ではないスカラー値によって、必要な型に対して値が型キャストされる場合でも挿入が失敗します。ただし、VALIDATEをキーワードCASTと一緒に使用すると、可能であればそのようなスカラー型キャストが実行されます。

例6-2 IS JSONチェック制約で型キャストを使用したJSONスキーマ検証

-- Constrain dataOfBirth to be of scalar type date.
CREATE TABLE mytable (
  jcol JSON VALIDATE
       '{"type"       : "object",
         "properties" : {"dateOfBirth" : {"extendedType" : "date"}}}');

-- Try to insert dataOfBirth field with ISO date string.
INSERT INTO mytable VALUES ('{"dateOfBirth" : "2018-04-11"}');
ERROR at line 1: 
ORA-40875: JSON schema validation error
CREATE OR REPLACE TABLE mytable (
  jcol JSON VALIDATE CAST
       '{"type"       : "object",
         "properties" : {"dateOfBirth" : {"extendedType" : "date"}}}');

INSERT INTO mytable VALUES ('{"dateOfBirth" : "2018-04-11"}');
1 row created.
-- Query with item-method type() shows the value is a DATE.
SELECT d.jcol.dateOfBirth.type() FROM mytable d;
D.JCOL.DATEOFBIRTH.TYPE()
-------------------------
date

6.3 JSONスキーマの生成

JSONスキーマは、既存の一連のJSON文書から、または他のデータベース・オブジェクト/データから生成(作成)できます。

JSON文書からJSONスキーマを生成する場合、スキーマは階層JSONデータ・ガイド(文書内のよくあるフィールドが説明されているフィールド(JSONスキーマおよびOracle固有)を含むJSON文書)になります。

通常、データ・ガイドは、既存の一連のJSON文書について構造を理解する手掛かりとなります。通常、生成されたままでは検証目的には適していませんが、検証に使用するために手作業で定義したスキーマの基準として利用できます。

「データ・ガイドの形式およびデータ・ガイドの作成方法」表23-2を参照してください。

JSONスキーマを一連のJSON文書から生成するかわりに、他のデータベース・データから生成できます。これを行うには、PL/SQLファンクションDBMS_JSON_SCHEMA.describeを使用し、次のいずれかを渡してスキーマを定義します。

  • 既存のリレーショナルビューまたはJSONリレーショナル二面性ビュー。JSONスキーマ内のオブジェクトに対応します。データベース表、ビューまたは二面性ビューからJSONスキーマへのマッピングは、表6-1を参照してください。

    生成されたスキーマは、表、ビューまたは二面性ビューに依存しません。そのデータベース・オブジェクトの定義は、スキーマが生成される場合にのみ使用されます。後でオブジェクト定義を変更しても、スキーマには影響しません。

  • 既存のSQLユーザー定義オブジェクト型インスタンスまたはコレクション型インスタンス(VARRAYまたはネストした表)。オブジェクト型インスタンスは、JSONスキーマ内のオブジェクトに対応します。コレクション型インスタンスは、JSON配列に対応します。オブジェクト型またはコレクション型のデータベース・インスタンスからJSONスキーマへのマッピングは、表6-1を参照してください。

    生成されたスキーマは、オブジェクトまたはコレクションの型に依存しません。型の定義は、スキーマの生成時にのみ使用されます。その後で型の定義を変更しても、スキーマには影響しません。

    記述するオブジェクト型インスタンスのタイプが別のオブジェクト型のサブタイプである場合、生成されたスキーマ(記述)には、スーパータイプから継承された属性に対応するフィールドがすべて含まれます。

  • アプリケーション使用方法ドメイン

    ドメインを使用すると、特定の型のデータの用途を示すことができます。ドメインの仕様には、データ型、デフォルト値、照合仕様、チェック制約、表示形式、目的の順序付けおよびドメイン記述のメタデータをJSON形式で含めることができます。ドメインはサブタイプを定義しません。ドメイン自体は、それが知らせるデータ型に対して実行できる操作を制限しません。

    たとえば、ドメインでは、特定のVARCHAR2列に電子メール・アドレスを格納するように指定できます。チェック制約として、関連する使用制約と検証ルールを強制適用できます。

  • SQL表、ビュー、オブジェクト型、コレクション型、ドメインまたは二面性ビュー用のSQLシノニム

    結果のJSONスキーマは、表、ビュー、オブジェクト型、コレクション型、ドメインまたは二面性ビューから生成されたものと同じです。

データベース表、ビュー、オブジェクト型またはコレクション型からJSONスキーマへのマッピングについては、「DBMS_JSON_SCHEMA.DESCRIBEで生成されたJSONスキーマ」を参照してください。

関連項目:

6.4 DBMS_JSON_SCHEMA.DESCRIBEで生成されたJSONスキーマ

このマッピングは、PL/SQLファンクションDBMS_JSON_SCHEMA.describeが、データベース表、ビュー、JSONリレーショナル二面性ビュー、オブジェクト型インスタンス、コレクション型インスタンス(VARRAYまたはネストした表)またはドメインからJSONスキーマを生成するために使用するものとして記述されています。

データベース・シノニムからのスキーマの生成は、同義のデータベース・オブジェクトからのスキーマの生成と同じです。たとえば、表のシノニムから生成されたJSONスキーマは、その表から直接生成されたスキーマと同じです。

表6-1では、データベース・オブジェクト(表、ビュー、JSONリレーショナル二面性ビュー、オブジェクト型インスタンスまたはコレクション型インスタンス)の一般プロパティから・JSONスキーマ・フィールドへのマッピングを指定します。

Oracle固有のJSONスキーマ・フィールドは、dbColumndbConstraintExpressiondbConstraintNamedbDomaindbFieldPropertiesdbForeignKeydbNoPrecheckdbObjectdbObjectPropertiesdbObjectTypedbPrimaryKeydbUniqueextendedTypesqlPrecisionsqlScaleおよびtitleです。

、通常のビューまたはJSONリレーショナル二面性ビューの場合、スキーマ・フィールドdbObjectTypeの値は"table""view"または"dualityView"であり、これはそれぞれ、そのスキーマが表、通常のビューまたは二面性ビューから導出(生成)されたことを示しています。フィールドtypeの値"object"は、スキーマは妥当なJSONデータがJSONオブジェクトであると想定していることを意味します。

オブジェクト型またはコレクション型のインスタンスの場合、スキーマ・フィールドdbObjectTypeの値は"type"であり、スキーマがユーザー定義のデータベース・データ型インスタンスから導出されたことを意味します。フィールドtypeの値は"object"または"array"であり、スキーマがそれぞれオブジェクト型インスタンスまたはコレクション型インスタンスから導出されたことを意味し、スキーマでは妥当なJSONデータがそれぞれJSONオブジェクトまたは配列であると想定していることを意味します。

アプリケーション使用方法ドメインの場合、スキーマ・フィールドdbObjectTypeの値は"domain"であり、これは、そのスキーマがドメインから導出されたということです。

ビューまたは二面性ビュー、およびオブジェクト型インスタンスの属性の場合は、スキーマ・フィールドpropertiesの値は、列名または属性名に対応するフィールド名があるJSONオブジェクトになります。このような各スキーマ・フィールドの値は、JSONオブジェクトであり、有効として許可されるJSON値(列または属性の値に対応する値)をまとめて指定するフィールドを持つJSONオブジェクトです。オブジェクト型インスタンスの場合: オブジェクトのタイプが別のオブジェクト型のサブタイプである場合、propertiesの値には、スーパータイプから継承された属性に対応するフィールドがすべて含まれます。

NOT NULL制約のある列は、生成されたJSONスキーマに従って有効であるデータの必須フィールドに対応します。これらの列名は、スキーマ・フィールドrequiredの配列値の要素です。主キー列と一意列の名前はそれぞれ、スキーマ・フィールドdbPrimaryKeyとスキーマ・フィールドdbUniqueの配列値の要素です。

表を記述するスキーマには、表定義で制約がNOPRECHECKと宣言されていない場合に、対応するJSONスキーマとして既知のチェック制約がある各列のサブスキーマが含まれます。含まれるサブスキーマは、対応するJSONスキーマで、列で許可されるデータを記述します

アプリケーションでは、この列記述スキーマを使用して、列に格納されるデータを、データベースに送信する前に検証できます。そのアプリケーション・データがすでにJSONの形式の場合は、JSONスキーマを直接使用してこの事前チェックを実行できます。それ以外の場合は、チェックする必要がある内容の宣言的な仕様(説明)として使用できます。

データベースが事前チェックできない(つまり、対応するJSONスキーマがない)と判断した列チェック制約、または表定義でNOPRECHECKと宣言されている列チェック制約は、かわりにスキーマ・フィールドdbNoPrecheckの(配列)値にリストされます。

CREATE TABLEまたはALTER TABLEを使用すると、データベースは、列チェック制約が事前チェック可能であることがわかっているかどうかを自動的に判断します。Oracle Database 23cより前に作成または最後に変更された制約の場合、事前チェック可能性は不明であるため、関数describeの出力には、このような制約のJSONスキーマは含まれず、配列dbNoPrecheckの制約もリストされません。

列チェック制約の既知の事前チェック可能性も、静的ディクショナリ・ビューALL_CONSTRAINTSDBA_CONSTRAINTSおよびUSER_CONSTRAINTSの列PRECHECKに記録されます。列値は、制約が事前チェック可能であると判断された場合はPRECHECK、事前チェック不可と判断された場合はNOPRECHECK、決定または宣言がまだ実行されていない場合はNULLです。デフォルトでは、Oracle Databaseリリース23cより前に作成されたチェック制約の値はNULLです。

コレクション型インスタンスの要素の場合、スキーマ・フィールドitemsの値は、JSON配列の要素ごとに許可されるJSON値(コレクション要素に許可される値に対応する値)をまとめて指定するフィールドを持つJSONオブジェクトです。スキーマ・フィールドmaxItemsは、JSON配列要素の最大数を指定します。

表6-1 データベース・オブジェクトのプロパティから導出されるJSONスキーマ・フィールド

フィールド(キーワード) 値の説明

dbColumn

Oracle固有。

参照されている列の名前。

dbConstraintExpression

Oracle固有。

同等のJSONスキーマがないか、表定義でNOPRECHECKと宣言されているチェック制約を定義するSQL式。dbNoPrecheckを参照してください。

dbConstraintName

Oracle固有。

同等のJSONスキーマがないか、表定義でNOPRECHECKと宣言されているチェック制約の名前。dbNoPrecheckを参照してください。

dbDomain

Oracle固有。検証ではなく、注釈のためにのみ使用されます。

関連するドメインの完全修飾名。ドメインに関連付けられている列にのみ表示されます。

dbFieldProperties

Oracle固有。

JSONリレーショナル二重ビューのまたはビューでサポートされているJSON文書のフィールドで許可される操作に関する情報。

値は配列であり、"update"および"check"要素を含むことができます。これらの説明は、dbObjectPropertiesの要素"updatable"および"check"と同じですが、dbFieldPropertiesの場合、指定の列または対応する文書フィールドにのみ適用されます。

dbForeignKey

Oracle固有。検証ではなく、注釈のためにのみ使用されます。

表またはビューの外部キー列に対応する検証対象のJSON値のオブジェクトを指定する要素を持つJSON配列。

dbNoPrecheck

Oracle固有。

同等のJSONスキーマがないか、表定義でNOPRECHECKと宣言されているチェック制約のオブジェクトの配列。各オブジェクトのフィールドは、dbConstraintNameおよびdbConstraintExpressionです。

指定されたチェック制約が事前チェック可能かどうかも、静的ディクショナリ・ビューALL_CONSTRAINTSDBA_CONSTRAINTSおよびUSER_CONSTRAINTSの列PRECHECKから得られます。

dbObject

Oracle固有。

データベース・オブジェクトの完全修飾名。

dbObjectProperties

Oracle固有。

JSONリレーショナル二面性ビュー全体でどの操作が許可されているかの情報。値は配列であり、次の要素を含むことができます:

  • "insertable" - 存在する場合は、標準のINSERT構文を使用して最上位のJSONオブジェクト全体をそのビュー定義に挿入できます。

  • "deletable" - 存在する場合は、標準のDELETE構文を使用して最上位のJSONオブジェクト全体をそのビュー定義から削除できます。

  • "updatable" - 存在する場合は、次のすべての操作が可能です:

    • 最上位のJSONオブジェクト全体を更新する。

    • 既存オブジェクトのフィールドを更新する。

    • 既存オブジェクトに新しいメンバーを挿入する。

    • 既存オブジェクトからメンバーを削除する。

  • "check" - 存在する場合は、そのビューでサポートされている文書の1つ以上のフィールドがETAG値(文書フィールド_metadataの値である、そのオブジェクトのフィールドETAGの値)の計算に寄与します。

dbObjectType

Oracle固有。検証ではなく、注釈のためにのみ使用されます。

スキーマ導出元のデータベース・オブジェクトの型: "table""view""dualityView""type"または"domain"

dbPrimaryKey

Oracle固有。検証ではなく、注釈のためにのみ使用されます。

表またはビューの外部キー列に対応する検証対象のJSON値のフィールド名を示す要素を持つJSON配列。

dbUnique

Oracle固有。検証ではなく、注釈のためにのみ使用されます。

表またはビューの一意列に対応する検証対象のJSON値のフィールド名を示す要素を持つJSON配列。

description

検証ではなく、注釈のためにのみ使用されます。

スキーマによって検証されるJSON値について説明するコメント(通常は、目的または意味です)。

extendedType

Oracle固有。

スキーマによって検証されるJSON値に指定されたJSON言語型。この値は文字列または文字列の配列です。

文字列で指定された型には、標準のJSONスキーマ・キーワードtypeでサポートされている標準の型を含めることができます。それ以外に、Oracle固有の型"binary""double""float""date""timestamp""timestampTz""ymInterval"および"dsInterval"を含めることもできます。

キーワードtypeextendedTypeを一緒に使用する場合は、互換性のある型を指定する必要があります。それ以外の場合は、フィールドによって対象とされるデータは有効とみなされません。(スキーマ自体の妥当性は、このような非互換性の影響を受けません)。

Oracle Databaseによって提供される検証では、JSON言語型の互換性は、Oracle SQLファンクション JSON_SERIALIZEで型のインスタンス間の変換が可能かどうかによって定義されます(「Oracle SQLファンクションJSON_SERIALIZE」を参照)。

items

JSON配列の各要素を指定するJSONオブジェクト。

コレクション型から導出されたスキーマの場合、そのフィールドはまとめてコレクション型のインスタンスの要素に対応するJSON値を指定します。

maxItems

JSON配列に許可される要素の最大数を指定するJSON数値。

コレクション型から導出されたスキーマの場合は、コレクション型のインスタンスに許可される要素の最大数です。

maxLength

検証対象のJSON文字列の最大長(文字数)。

minLength

検証対象のJSON文字列の最小長(文字数)。

properties

検証対象のJSONオブジェクト内の同じフィールドの値を指定するフィールドを持つJSONオブジェクト。

フィールドでは、表またはビューの列データまたはオブジェクト型の属性データに対応するデータを指定します。

required

検証対象のJSON値に必要なフィールドの名前を示す要素を持つJSON配列。

表またはビューから導出されたスキーマの場合は、表またはビューのNOT NULL列の名前を示します。

sqlPrecision

Oracle固有。検証ではなく、注釈のためにのみ使用されます。

JSON言語数値型(numberdoublefloat)またはtimestamp型のインスタンスの精度。

sqlScale

Oracle固有。検証ではなく、注釈のためにのみ使用されます。

JSON言語数値型のインスタンスのスケール。

title

検証ではなく、注釈のためにのみ使用されます。

Oracle固有の使用: スキーマが導出されるデータベース・オブジェクト(表、ビュー、JSONリレーショナル二面性ビュー、オブジェクト型、コレクション型またはドメイン)の名前。

type

スキーマによって検証されるJSON値に指定されたJSON言語型。この値は文字列または文字列の配列です。

この文字列によって名付けられる型は、標準の型(Oracle固有ではない型)、"null""boolean""object""array""number"および"string"、ならびに小数部分がゼロの任意の数値と一致する"integer"のみです。

関連項目:

6.5 列チェック制約が事前チェック可能かどうかの明示的な宣言

表を作成または変更するときに、個々の列チェック制約を明示的に宣言して、データベースの外部で事前チェック可能(または不可)にできます。事前チェック可能と宣言した制約が実際には事前チェック可能でない場合は、エラーが発生します。

事前チェック可能なチェック制約は、(1)同等のJSONスキーマを持ち、(2)事前チェック不可として明示的に宣言されていない制約です。

列制約が事前チェック可能な場合、アプリケーションはデータベースにデータを送信する前に事前検証できます。このクライアント側での無効なデータの検出によって、アプリケーションの回復性が向上し、潜在的なシステム停止時間が短縮される可能性があります。

アプリケーションがJSONデータを使用する場合、同等のJSONスキーマを直接使用して事前チェックを実行できます。そうでない場合、スキーマは必要な検証の種類の説明として使用できます。

表を作成または変更すると、その列チェック制約が自動的に検査され、事前チェック可能かどうかが確認されます。既知の事前チェック可能性に関するこの情報は、2つの場所で利用できるようになります。

  • 既存の表のPL/SQLファンクションDBMS_JSON_SCHEMA.describeによって生成されるJSONスキーマ。

    チェック制約と同等のJSONスキーマが、表を説明するスキーマに含まれています。事前チェックできないチェック制約は、表スキーマ・プロパティdbNoPrecheckにリストされます。

  • 静的ディクショナリ・ビューALL_CONSTRAINTSDBA_CONSTRAINTSおよびUSER_CONSTRAINTSの列PRECHECK

    ビュー行にはチェック制約がリストされます。列PRECHECKの値は、制約が事前チェック可能であることがわかっている場合はPRECHECK、事前チェック可能でないことがわかっている場合はNOPRECHECK、そうでない場合はNULLです。

    NULLは、制約の事前チェック可能性がまだ決定(設定)されていないことを示します。これは、Oracle Database 23cより前に作成された制約のデフォルトの場合です。

事前チェック不可能なチェック制約がある表の作成または変更を明示的に禁止できます。このためには、CREATE文またはALTER TABLE文の制約にキーワードPRECHECKを追加します。制約が事前チェック可能でない場合、エラーが発生します。

特に、事前チェック可能性の自動決定が導入されたOracle Databaseリリース23cより前に作成された列チェック制約に対して、キーワードPRECHECKALTER TABLEとともに使用できます。キーワードPRECHECKを適用する制約に対してエラーが発生しない場合、制約は事前チェック可能であることがわかります。この場合、PL/SQLファンクションDBMS_JSON_SCHEMA.describeおよびディクショナリ・ビューALL_CONSTRAINTSDBA_CONSTRAINTSおよびUSER_CONSTRAINTSは、事前チェック可能な制約について前述のように処理されます。

キーワードNOPRECHECKを使用すると、事実上、制約が事前チェック可能でないことを宣言することになります。これは通常、データがデータベースの外部で事前チェックされないことを意味します。NOPRECHECKを使用しても、制約に相当するJSONスキーマが存在しないことを意味するものではなく、アプリケーションの事前チェックが妨げられることもありません。ただ、データが事前チェック可能であることを期待しないように言っているにすぎません。

デフォルトでは、列制約が事前チェック可能であり、列に挿入されるデータがアプリケーションによって実際に事前チェックされている場合でも、データベースでは引き続きチェック制約を使用してデータを検証します。つまり、データはアプリケーションによって事前検証され、データベースによって検証されます。

キーワードPRECHECKとともにキーワードDISABLE RELYを制約に追加した場合、データベースは制約を使用して列データを検証しないため、制約が満たされることは保証されません。問合せオプティマイザは、制約が満たされていることを想定するため、データが無効な場合に失敗する可能性がある実行計画を生成します。アプリケーションのみで列データの検証を行う場合は、DISABLE RELYを使用します。

例6-3 列制約の事前チェック

サンプル・スキーマhrの表employeesには、(describe hr.employeesから)列salaryおよびcommission_pctが含まれています。

Name           Null?    Type
-------------- -------- -----------
SALARY         NOT NULL NUMBER(8,2)
COMMISSION_PCT NOT NULL NUMBER(2,2)

アプリケーションがこれら2つの列を事前チェックできると想定していることをデータベースに通知するために、開発者はキーワードPRECHECKを使用して列制約を追加します。給与は2000以上で、歩合の割合を6000未満にする必要があります。

ALTER TABLE employees
  ADD CONSTRAINT min_salary CHECK (salary >= 2000) PRECHECK;

ALTER TABLE employees
  ADD CONSTRAINT max_bonus CHECK ((salary * commission_pct) < 6000) PRECHECK;

チェック制約max_bonusには同等のJSONスキーマがないため、事前チェックできません。その結果、制約の作成でエラーが発生します。

ORA-40544: CHECK expression of 'MAX_BONUS' constraint not possible to use as PRECHECK condition

制約max_bonusには対応するJSONスキーマがありません。これは定義上、事前チェック可能ではないことを意味します。アプリケーションでは、制約が満たされるように、挿入または更新する行の給与とコミッションの割合を事前検証できます。これは、SQL式(salary * commission_pct) < 6000と同等のJSONスキーマを使用して行うことはできません。

PRECHECKを受け入れるには、制約の作成から削除する必要があります(エラーは発生しません)。

ALTER TABLE employees
  ADD CONSTRAINT max_bonus CHECK ((salary * commission_pct) < 6000);

チェック制約を定義した後、表hr.employeesDBMS_JSON_SCHEMA.describeの出力には制約min_salaryと同等のJSONスキーマが含まれ、フィールドdbNoPrecheckの配列値には制約max_bonusのエントリが含まれます。

SELECT DBMS_JSON_SCHEMA.describe('EMPLOYEES');
{"title"         : "EMPLOYEES",
 "dbObject"      : "HR.EMPLOYEES",
 "dbObjectType"  : "table",
 ...
 "dbNoPrecheck"  : [ {"dbConstraintName"       : "MAX_BONUS",
                      "dbConstraintExpression" :
                        "(salary * commission_pct) < 6000"} ],
 ...
 "properties"    : {...
                    "SALARY" : {"extendedType" : "number",
                                "allOf"        : [ {"exclusiveMinimum" : 2000} ]}
                    ...
                   }}

関連項目: