20 JSON用のPL/SQLオブジェクト型の概要

PL/SQLオブジェクト型を使用すると、インメモリーJSONデータをプログラム的に細かく構成および操作できます。テキストのJSONデータに戻って、イントロスペクション、変更およびシリアライズを行えます。

主なPL/SQL JSONオブジェクト型には、JSON_ELEMENT_TJSON_OBJECT_TJSON_ARRAY_TおよびJSON_SCALAR_Tがあります。この他にも、使用頻度が比較的少ないオブジェクト型としてJSON_KEY_LISTがあります。これは、VARCHAR2(4000)のVARRAYです。オブジェクト型は、抽象データ型(ADT)とも呼ばれます。

これらのJSONオブジェクト型は、データベース内に格納されたJSONデータのインメモリーで(ツリーのような)階層型のプログラム的表現を提供します。Foot 1

次のことを行うために、オブジェクト型を使用してJSONデータをインメモリーでプログラム的に操作できます。

  • 既存のJSONデータの構造、型または値をチェックします。たとえば、指定したオブジェクト・フィールドの値が特定の条件を満たしているかどうかをチェックします。

  • 既存のJSONデータを変換します。たとえば、住所や電話番号の形式を特定の形式に従うように変換します。

  • データが表す特性に一致するプログラミング・ルールを使用して、JSONデータを作成します。たとえば、JSONオブジェクトとして表す製品が可燃性のあるものだった場合に、安全情報を表すフィールドを含めます。

PL/SQLオブジェクト型インスタンスは一時的です。ここに含まれる情報を永続的に格納するには、VARCHAR2またはLOBデータにそれらをシリアル化する必要があります。これらをデータベース表またはJava Database Connectivity (JDBC)などのデータベース・クライアントへのマーシャルに格納できます。

インメモリーでのオブジェクト型インスタンスの構成は、JSONテキストを解析することで一括して行うか、空のオブジェクトまたは配列インスタンスから始めてそこにオブジェクト・メンバーまたは配列要素を追加することで段階的に行うかのいずれかの方法で実施します。

使用されていないオブジェクト型インスタンスは自動的なガベージ・コレクションによって処理されるため、必要なくなったインスタンスで使用されたメモリーの解放は行うことができず、その必要もありません。

通常は、PL/SQLオブジェクト型インスタンスを構成し、おそらく様々な方法でプログラム的に利用した後で、VARCHAR2CLOBまたはBLOBのデータ型のインスタンスにシリアライズします。つまり、インメモリーのJSONデータの一時的な表現を、データベースの永続的な表現に変換します。(または、出力のためのテキストとしてのみシリアライズする場合もあります。)

JSONオブジェクト型の相互関係

JSON_ELEMENT_Tは、他のJSONオブジェクト型のスーパータイプです。各JSONオブジェクト型がサブタイプとしてこれを拡張します。サブタイプJSON_OBJECT_TおよびJSON_ARRAY_Tは、それぞれJSONオブジェクトと配列に対して使用されます。サブタイプJSON_SCALAR_Tは、スカラーJSON値である文字列、数値、ブール値のtrueおよびfalse、値nullで使用されます。

JSON_ELEMENT_Tのインスタンスは、JSONテキストの解析によってのみ構成できます。解析によって、JSONデータのインメモリー表現である、JSON_ELEMENT_Tインスタンスが作成されます。型がJSON_ELEMENT_Tまたは型JSON_SCALAR_Tの空のインスタンスは構成できません。

JSON_OBJECT_TJSON_ARRAY_Tには、型と同じ名前のコンストラクタ関数があり、それぞれJSONオブジェクトまたは配列の空の(インメモリー)表現のインスタンスをその型で構成するために使用できます。その後、PL/SQLオブジェクト型インスタンスとして表されるオブジェクト・メンバーまたは配列要素を追加して、必要に応じてこのオブジェクトまたは配列にデータを入力できます。

PL/SQLファンクションtreatを使用して、JSON_ELEMENT_Tのインスタンスをサブタイプ・インスタンスにキャストできます。たとえば、treat(elt as JSON_OBJECT_T)はインスタンスeltをJSONオブジェクト(JSON_OBJECT_Tのインスタンス)としてキャストします。

解析関数

静的関数parseには、引数としてVARCHAR2CLOBまたはBLOBの型のインスタンスを指定できます。この関数は、各インスタンスをJSONテキストとして解析し、JSON_ELEMENT_TJSON_OBJECT_TまたはJSON_ARRAY_T型のインスタンスを戻します。BLOBでは、エンコーディングがUTF-8のデータのみを使用できます。parseの入力が整形式のJSONデータではない場合や、エンコーディングがUTF-8ではない場合には、エラーが発生します。

シリアライズ・メソッド

解析では、入力のJSONデータをテキストとして受け入れ、PL/SQL JSONオブジェクト型のインスタンスを戻します。シリアライズでは、基本的に反対のことが行われます。JSONデータのPL/SQLオブジェクト表現にシリアライズを適用すると、そのオブジェクトのテキスト表現が戻されます。シリアライズ・メソッドの名前は、接頭辞to_から始まります。たとえば、メソッドto_string()をJSONオブジェクト型のインスタンスに適用すると、そのインスタンスの文字列(VARCHAR2)表現が戻されます。

ほとんどのシリアライズ・メソッドはメンバ関数です。ただし、CLOBまたはBLOBインスタンスとしてのシリアライズの場合は、メンバ関数メンバー・プロシージャの2つの形式のメソッドがあります。メンバ関数は、引数を受け入れません。この場合は、シリアライズの宛先として一時的なLOBが作成されます。メンバー・プロシージャはLOB IN OUT引数を受け入れます(メソッドto_clobの場合はCLOBインスタンス、メソッドto_blobの場合はBLOB)。このように、シリアライズされた表現に使用するLOB (空の可能性もある)に渡します。

getterメソッドとsetterメソッド

JSON_OBJECT_TおよびJSON_ARRAY_Tには、getterメソッドとsetterメソッドがあります。これらはそれぞれ、特定のオブジェクト・フィールドの値、または特定の配列要素の位置の値を取得および更新します。

getterメソッドには2つの種類があります。

  • メソッドget()は、メソッドを適用した元のオブジェクトへの参照を、型JSON_ELEMENT_Tのインスタンスとして戻します。つまり、メソッドの適用対象のオブジェクトは参照渡しされます。その後、戻されたJSON_ELEMENT_Tインスタンスを変更した場合、変更内容はget()を適用した元のオブジェクトに適用されます。

  • メソッド名に接頭辞get_が付くgetterメソッドは、適用されたオブジェクトまたは配列内で対象となった任意のデータのコピーを戻します。このデータは参照されるのではなく、値によって渡されます

    たとえば、メソッドget_string()JSON_OBJECT_Tインスタンスに適用した場合、指定されたフィールドを引数として渡すと、そのフィールドの値の文字列のコピーが戻されます。get_string()JSON_ARRAY_Tインスタンスに適用した場合は、指定した要素の位置を引数として渡すと、配列内のその位置にある文字列のコピーを戻します。

シリアライズ・メソッドと同様に、ほとんどのgetterメソッドはメンバ関数です。ただし、指定したオブジェクト・フィールドの値か、指定した配列の位置にある要素をCLOBまたはBLOBインスタンスとして戻すget_clob()およびget_blob()のメソッドには、(シリアライズ・メソッドto_clob()およびto_blob()のように)メンバ関数とメンバー・プロシージャの2つの形式があります。メンバ関数は、対象となるオブジェクト・フィールドまたは配列の位置以外の引数は受け入れません。一時LOBインスタンスを作成して戻します。メンバー・プロシージャはLOB IN OUT引数も受け入れます(get_clobの場合はCLOBget_blobの場合はBLOB)。このように、メンバー・プロシージャを使用する(空の可能性もある)LOBインスタンスに渡すことができます。

setterメソッドは、put()put_null()および(JSON_ARRAY_Tのみについては)append()です。これらのメソッドは、対象のオブジェクト・フィールドまたは配列要素の値を設定して、適用されたオブジェクトまたは配列のインスタンスを更新します。注意: setterメソッドは、変更されたインスタンスのコピーを戻すかわりに、既存のインスタンスを変更します

メソッドappend()は、配列インスタンスの末尾に新しい要素を追加します。メソッドput_null()は、オブジェクト・フィールドまたは配列要素の値をJSON nullに設定します。

メソッドput()では、2つ目の引数に設定する新しい値を指定する必要があります(オブジェクト・フィールド名または配列要素の位置の他に)。配列の場合は、put()は、オプションで3つ目の引数OVERWRITEも受け入れます。これは、BOOLEAN値で(デフォルトはFALSE)、指定された位置にある既存の値を置換するかどうかを示します。

  • オブジェクトに、同じ名前のフィールドがすでにある場合、put()その値を置き換えて新しい値にします。

  • 配列の指定された位置に要素がすでにあった場合は、デフォルトの動作として、put()はその要素とそれに続くすべての要素を先に移動させ(それらの位置を1つずつインクリメントして)、新しい要素のためのスペースを作成します。これで、新しい要素が指定された位置に配置されます。ただし、オプションの引数OVERWRITEが指定されていてTRUEの場合、指定された位置の既存の要素は、単純に新しい要素で置き換えられます

イントロスペクション・メソッド

JSON_ELEMENT_Tには、インスタンスがJSONオブジェクト、配列、スカラー、文字列、数値またはブール値かどうか、またはJSON値truefalseまたはnullであるかどうかを判断するために使用できる、イントロスペクション・メソッドがあります。これらのメソッドの名前は、接頭辞is_で始まります。これらは、BOOLEAN値を戻す述語です。

この型には、イントロスペクション・メソッドget_size()もあります。これは、JSON_OBJECT_Tインスタンスのメンバーの数と、JSON_ARRAY_Tインスタンスの要素数を戻します(JSON_SCALAR_Tインスタンスに対して1を戻します)。

JSON_ELEMENT_Tには、イントロスペクション・メソッドis_date()is_timestamp()もあります。これらは、インスタンスが日付またはタイムスタンプを表すかどうかをテストします。JSONには、日付またはタイムスタンプのネイティブ・タイプはありません。これらは、通常、JSON文字列を使用して表されています。ただし、JSON_ELEMENT_Tインスタンスが、SQLデータ型DATEまたはTIMESTAMPのSQLデータを使用して構成されている場合、この型情報は、PL/SQLのオブジェクト表現用に保持されます。

日付とタイムスタンプのデータは、PL/SQLオブジェクト型JSON_SCALAR_Tを使用して表されます。この型のインスタンスは、直接構成することはできません。ただし、このような値をオブジェクト(フィールド値として追加)または配列(要素として)にメソッドput()を使用して追加できます。メソッドget()を使用してこれを取得すると、JSON_SCALAR_Tインスタンスが戻されます。

JSON_OBJECT_TおよびJSON_ARRAY_Tには、イントロスペクション・メソッドget_type()があります。これは、対象となるオブジェクト・フィールドまたは配列要素のJSON型を戻します(VARCHAR2インスタンスとして)。また、型JSON_OBJECT_Tには2つのイントロスペクション・メソッドがあります。has()は、オブジェクトに指定された名前のフィールドがすでにある場合はTRUEを戻します。また、get_keys()は、PL/SQLオブジェクト型JSON_KEY_LISTのインスタンスを戻します。これは、VARCHAR2(4000)のVARRAYです。VARRAYには、指定されたJSON_OBJECT_TインスタンスにあるフィールドFoot 2 Footref 2の名前が含まれます。 

その他のメソッド

JSON_OBJECT_TおよびJSON_ARRAY_Tには、次のメソッドがあります。

  • remove(): 指定されたフィールドまたは指定された位置の配列要素を持つオブジェクト・メンバーを削除します。

  • clone(): メソッドが適用されるオブジェクトまたは配列の(ディープ)コピーを作成および戻します。このコピーを変更しても、元のオブジェクトまたは配列に影響はありません。

JSON_OBJECT_Tにはメソッドrename_key()があります。これは、指定されたオブジェクト・フィールドの名前を変更します。Footref 2指定された新しい名前が既存のフィールドの名前だった場合は、エラーが発生します。

関連項目:



脚注の凡例

脚注1: これは、Document Object Model (DOM)を使用してXMLデータで使用可能なものと類似しています。DOMは、言語やプラットフォームに依存しないオブジェクト・モデルおよびAPIで、XMLドキュメントの構造へのアクセス用にWorld Wide Web Consortium (W3C)から推奨されています。
脚注2: オブジェクト・フィールドは、オブジェクトの「キー」と呼ばれることもあります。