285 JSONのデータ構造

PL/SQLでJSONデータを処理するには、次のデータ構造を使用できます。

285.1 JSON_ELEMENT_Tオブジェクト・タイプ

JSON_ELEMENT_Tは、JSON_OBJECT_TJSON_SCALAR_TおよびJSON_ARRAY_Tオブジェクト・タイプのスーパータイプです。

説明

次の点に注意してください。

  • JSON_ELEMENT_Tのインスタンスを作成するには、parseファンクションを使用します。詳細は、次の項「コンストラクタ」を参照してください。

  • 空のJSON_ELEMENT_Tインスタンスを作成することはできません。空のJSONコンテナを作成するには、いずれかのサブタイプに基づいてJSONコンテナを作成します。

  • JSON_ELEMENT_Tをサブタイプ(JSON_OBJECT_Tなど)に変換するには、TREAT ASを使用して明示的な変換を実行する必要があります。次に例を示します。

    TREAT (elem AS JSON_OBJECT_T)

コンストラクタ

JSON_ELEMENT_Tインスタンスは、parseファンクションを使用して作成します。このファンクションは入力としてVARCHAR2、CLOBまたはBLOBデータを取り、JSON_ELEMENT_Tインスタンスを戻します。

STATIC FUNCTION parse(json VARCHAR2) RETURN JSON_ELEMENT_T
STATIC FUNCTION parse(json CLOB)     RETURN JSON_ELEMENT_T
STATIC FUNCTION parse(json BLOB)     RETURN JSON_ELEMENT_T

UTF8でエンコードされたJSONのみがBLOBとして渡されます。

parseファンクションは、入力としてJSON文字列を取り、JSONデータの内部表現を設定します。提供された入力が有効なJSONでない場合、エラー・メッセージが生成されます。有効なJSONは、"IS JSON" SQL条件のLAXチェックに合格する必要があります。

シリアライズ

シリアライズは、parseファンクションの逆です。シリアライズ操作はJSONデータのインメモリー表現を取り、それを文字列に出力します。シリアライズのファンクションおよびプロシージャは次のとおりです。

MEMBER FUNCTION to_String    RETURN VARCHAR2
MEMBER FUNCTION to_Number    RETURN NUMBER
MEMBER FUNCTION to_Date      RETURN DATE
MEMBER FUNCTION to_Timestamp RETURN TIMESTAMP
MEMBER FUNCTION to_Boolean   RETURN BOOLEAN
MEMBER FUNCTION to_Clob      RETURN CLOB
MEMBER FUNCTION to_Blob      RETURN BLOB

MEMBER PROCEDURE to_Clob(c IN OUT CLOB)
MEMBER PROCEDURE to_Blob(c IN OUT BLOB)

to_Clobおよびto_Blobプロシージャは、CLOBまたはBLOB入力を受け入れます。これによって、シリアライズの宛先として使用されるLOBを提供できます。たとえば、EMPTY_LOBを提供できます。入力のLOBはNULLにできません。

to_Clobファンクションを使用すると、新しいCLOBが作成されます。最初にCLOBを作成しない場合は、to_Clobまたはto_Blobファンクションを使用できます。これらのファンクションはパラメータを取らずに、一時的なLOBを生成します。

to_Blobは、UTF8形式へのシリアライズのみを行います。

イントロスペクション

イントロスぺクションを行うと、JSONオブジェクトを変更することなくJSONオブジェクトのプロパティを検出できます。イントロスペクションのファンクションは次のとおりです。

MEMBER FUNCTION is_Object    RETURN BOOLEAN
MEMBER FUNCTION is_Array     RETURN BOOLEAN
MEMBER FUNCTION is_Scalar    RETURN BOOLEAN
MEMBER FUNCTION is_String    RETURN BOOLEAN
MEMBER FUNCTION is_Number    RETURN BOOLEAN
MEMBER FUNCTION is_Boolean   RETURN BOOLEAN
MEMBER FUNCTION is_True      RETURN BOOLEAN
MEMBER FUNCTION is_False     RETURN BOOLEAN
MEMBER FUNCTION is_Null      RETURN BOOLEAN
MEMBER FUNCTION is_Date      RETURN BOOLEAN
MEMBER FUNCTION is_Timestamp RETURN BOOLEAN
MEMBER FUNCTION get_Size     RETURN NUMBER

get_sizeファンクションの戻り値は、JSONタイプによって異なります。

  • スカラーの場合、1が戻されます。

  • オブジェクトの場合、キーの数が戻されます。

  • 配列の場合、アイテムの数が戻されます。

JSONの性質上、日付とタイムスタンプはサポートされません。通常、これらは文字列としてモデル化されます。DOM APIを使用すると、日付とタイムスタンプをスカラー値として追加し、JSONへのシリアライズまで保存できます。シリアライズの時点で、これらはISO 8601形式に準じて文字列として出力されます。タイプが日付またはタイムスタンプのSQL値が追加された場合、is_Dateおよびis_Timestampファンクションはtrueを戻します。日付が文字列として(たとえば、ISO 8601として)追加された場合、is_Dateおよびis_Timestampファンクションはfalseを戻します。Oracle変換ファンクションto_Dateおよびto_Timestampを使用して、日付およびタイムスタンプの文字列表現をOracle表現に変換できます。

エラー処理

JSON処理のエラー処理のレベルを設定できます。すべての不一致に対してエラーを生成する必要がないこともあります。on_Errorプロシージャを使用すると、どのような場合にエラーを生成するかを指定できます。

MEMBER PROCEDURE on_Error(value NUMBER)

on_Errorプロシージャは、PL/SQL操作(getコールなど)の間にエラーが検出された場合に実行する処理を定義します。

デフォルトでは、エラーを生成せずにNULLを戻します。

JSON_ELEMENT_TインスタンスでOn_errorを起動すると、それ以降のすべてのコールに対するエラー動作が設定されます。動作をデフォルトにリセットするには、on_Error(0)をコールできます。

valueパラメータの値は、次のとおりです。

表285-1 ON_ERRORプロシージャのvalueパラメータの値

説明
0 デフォルト動作(エラーを生成せずにNULLを戻す)にリセットします。
1 すべてのエラーを生成します。
2 値が検出されない場合、エラーを生成します。
3 データ型が一致しない場合(たとえば、文字列値に対してGET_NUMBERをコールした場合など)にエラーを生成します。
4 入力が無効な場合(たとえば、配列が範囲外の場合など)にエラーを生成します。

値を組み合せることができます。たとえば、3と4の組合せを表す7を指定できます。

次の例では、"a"の値が"xyz"であるために数値に変換できず、エラーが生成されます。on_Errorプロシージャがコールされていない場合、NULLが戻されますが、エラーは生成されません。

declare
 	jo JSON_OBJECT_T;
begin
 	jo := JSON_OBJECT_T.parse('{a:"xyz"}');
 	jo.On_error(1);
 	dbms_output.put_line(jo.get_Number('a'));
end;
/

285.2 JSON_OBJECT_Tオブジェクト・タイプ

JSON_OBJECT_Tは、JSON_ELEMENT_Tオブジェクト・タイプのサブタイプです。これは、JSONのオブジェクト構造に対応しています。

コンストラクタ

次のコンストラクタを使用して、空のJSON_OBJECT_Tインスタンスを作成できます。

   CONSTRUCTOR FUNCTION JSON_OBJECT_T RETURN SELF AS RESULT

次のいずれかのparseファンクションを使用して、JSON_OBJECT_Tインスタンスを作成できます。

STATIC FUNCTION parse(json VARCHAR2) RETURN JSON_OBJECT_T
STATIC FUNCTION parse(json CLOB)     RETURN JSON_OBJECT_T
STATIC FUNCTION parse(json BLOB)     RETURN JSON_OBJECT_T

また、次のいずれかのコンストラクタを使用して、JSON_OBJECT_Tインスタンスを作成することもできます。

CONSTRUCTOR FUNCTION JSON_OBJECT_T(jsn VARCHAR2) RETURN SELF AS RESULT,
CONSTRUCTOR FUNCTION JSON_OBJECT_T(jsn CLOB) RETURN SELF AS RESULT,
CONSTRUCTOR FUNCTION JSON_OBJECT_T(jsn BLOB) RETURN SELF AS RESULT,
CONSTRUCTOR FUNCTION JSON_OBJECT_T(e JSON_ELEMENT_T) RETURN SELF AS RESULT

UTF8でエンコードされたJSONのみがBLOBとして渡されます。

parseファンクションは、入力としてJSON文字列を取り、JSONデータの内部表現を設定します。提供された入力が有効なJSONオブジェクトでない場合、エラー・メッセージが生成されます。入力は配列でなくJSONオブジェクトを指定する必要があります。

取得のファンクションおよびプロシージャ

次のファンクションおよびプロシージャを使用すると、JSONオブジェクトの値を取得できます。

MEMBER FUNCTION get(key VARCHAR2)           RETURN JSON_ELEMENT_T
MEMBER FUNCTION get_String(key VARCHAR2)    RETURN VARCHAR2
MEMBER FUNCTION get_Number(key VARCHAR2)    RETURN NUMBER
MEMBER FUNCTION get_Date(key VARCHAR2)      RETURN DATE
MEMBER FUNCTION get_Timestamp(key VARCHAR2) RETURN TIMESTAMP
MEMBER FUNCTION get_Boolean(key VARCHAR2)   RETURN BOOLEAN
MEMBER FUNCTION get_Clob(key VARCHAR2)      RETURN CLOB
MEMBER FUNCTION get_Blob(key VARCHAR2)      RETURN BLOB
MEMBER FUNCTION get_Object(key VARCHAR2)    RETURN JSON_OBJECT_T
MEMBER FUNCTION get_Array(key VARCHAR2)     RETURN JSON_ARRAY_T

MEMBER PROCEDURE get_Clob(key NUMBER, c IN OUT CLOB)
MEMBER PROCEDURE get_Blob(key NUMBER, c IN OUT BLOB)

ノート:

  • getファンクションには参照セマンティクスがあります。つまり、戻されたJSON_ELEMENT_Tが変更されると、包含するJSON_ELEMENT_Tも変更されます。詳細は、次の項「参照セマンティクス」を参照してください。

  • GET_STRINGファンクションは、まだ文字列でない値を文字列に変換します。したがって、IS_STRINGがfalseを戻した場合でも、GET_STRINGファンクションはnullでない値を戻します。

  • すべてのgetファンクションは、可能な場合に変換を実行します。変換が可能でない場合、ON_ERRORの設定値に応じてエラーが生成されることがあります。

GET_CLOBおよびGET_BLOBプロシージャは、CLOBまたはBLOBを入力として受け入れます。これによって、シリアライズの宛先として使用されるLOBを提供できます。たとえば、EMPTY_LOBを提供できます。このかわりにGET_CLOBファンクションを使用すると、新しいCLOBが暗黙的に作成されます。入力のLOBはNULLにできません。最初にBLOBまたはCLOBを作成しない場合は、GET_CLOBまたはGET_BLOBファンクションを使用できます。これらのファンクションはパラメータを取らずに、一時的なLOBを生成します。

GET_BLOBは、UTF8形式へのシリアライズのみを行います。

設定のプロシージャ

次のプロシージャを使用すると、JSONオブジェクトの値を設定できます。値が存在する場合、その値は上書きされます。

MEMBER PROCEDURE put(key VARCHAR2, value JSON_ELEMENT_T)
MEMBER PROCEDURE put(key VARCHAR2, value VARCHAR2)
MEMBER PROCEDURE put(key VARCHAR2, value NUMBER)
MEMBER PROCEDURE put(key VARCHAR2, value BOOLEAN)
MEMBER PROCEDURE put(key VARCHAR2, value DATE)
MEMBER PROCEDURE put(key VARCHAR2, value TIMESTAMP)
MEMBER PROCEDURE put_Null(key VARCHAR2)

イントロスペクションのファンクション

イントロスぺクションを行うと、JSONオブジェクトを変更することなくJSONオブジェクトのプロパティを検出できます。イントロスペクションのファンクションは次のとおりです。

MEMBER FUNCTION has(key VARCHAR2)      RETURN BOOLEAN
MEMBER FUNCTION get_Type(key VARCHAR2) RETURN VARCHAR2
MEMBER FUNCTION get_Keys               RETURN JSON_KEY_LIST

GET_KEYSファンクションは、JSON_KEY_LISTのオブジェクト・タイプ(VARCHAR2(4000)のVARRAY)を戻します。このVARRAYには、JSONオブジェクトのキーの名前が含まれます。次の例では、VARRAYのアイテムをウォークスルーして、すべてのキー名を含むJSON_ARRAY_Tオブジェクトを作成します。

declare
  jo JSON_OBJECT_T;
  ja JSON_ARRAY_T;
  keys JSON_KEY_LIST;
  keys_string VARCHAR2(100);

begin
  ja := new JSON_ARRAY_T;
  jo := JSON_OBJECT_T.parse('{"name":"fred",
                              "jobTitle":"codemonkey",
                              "projects":["json", "xml"]}');
  keys := jo.get_keys;
  for i in 1..keys.count loop
     ja.append(keys(i));
  end loop;

  keys_string := ja.to_string;
  dbms_output.put_line(keys_string);
end;
/

出力は次のとおりです。

["name","jobTitle","projects"]

変更のプロシージャ

次のプロシージャを使用すると、JSONオブジェクトのキーを削除または名前変更できます。

MEMBER PROCEDURE remove(key VARCHAR2)
MEMBER PROCEDURE rename_Key(keyOld VARCHAR2, keyNew VARCHAR2)

重複するキー名はサポートされておらず、エラーが発生します。

Cloneファンクション

このファンクションは、JSONオブジェクトのコピーを作成します。参照セマンティクスは値セマンティクスに変更されます。

MEMBER FUNCTION clone RETURN JSON_OBJECT_T

参照セマンティクス

JSON_ELEMENT_Tオブジェクトを戻すgetファンクションをコールすると常に、コピーでなく複合値への参照が戻されます。つまり、戻された値を変更すると、そのコンテナに影響を与えます。次の例を参照してください。

declare
  data    JSON_OBJECT_T;
  address JSON_OBJECT_T;
  zip     number;

begin

  data := new JSON_OBJECT_T('{
	"first": "John",
	"last": "Doe",
	"address": {
		"country": "USA",
		"zip": "94065"
	}
  }'); 

  address := data.get_object('address');
  dbms_output.put_line(address.to_string);
  
  -- 1) VALUE SEMANTICS for scalar values 
  -- (changing the value has no effect on container)
  zip := address.get_number('zip');
  dbms_output.put_line(zip);
  zip := 12345;
  dbms_output.put_line(zip);
  -- address is still the same
  dbms_output.put_line(address.to_string);


  -- 2) REFERENCE SEMANTICS for complex values
  --    'address' is a reference to the complex address values inside 'data'
  address.put('zip', 12345);
  address.put('street', 'Detour Road');
  dbms_output.put_line(data.to_string);
end;
/

参照セマンティクスを使用しない場合は、cloneファンクションを使用して、戻されたオブジェクトのコピーを作成できます。これにより、値がそのコンテナから切り離されます。前述の例でaddressオブジェクトのコピーを作成する場合、

address := data.get_object('address');

という行を、次の行で置き換えます。

address := data.get_object('address').clone;

これ以降は、アドレスを変更しても、データ包含オブジェクトの値に影響を与えません。

更新の例

次の例では、アイテムの価格を10%更新します。

WITH
  FUNCTION updatePrice(jsonTxt in VARCHAR2 ) RETURN VARCHAR2 IS
  jo JSON_OBJECT_T;
  oldPrice NUMBER;

  BEGIN
    jo := new JSON_OBJECT_T(jsonTxt);
    oldPrice := jo.get_number('price');
    jo.put('price', oldPrice * 1.1);
    RETURN jo.to_string();
  END;
SELECT updatePrice(col)
FROM   t1;

285.3 JSON_ARRAY_Tオブジェクト・タイプ

JSON_ARRAY_Tは、JSON_ELEMENT_Tオブジェクト・タイプのサブタイプです。JSON_ARRAY_Tは、JSONの配列構造に対応しています。

コンストラクタ

次のコンストラクタを使用して、空のJSON_ARRAY_Tインスタンスを作成できます。

   CONSTRUCTOR FUNCTION JSON_ARRAY_T RETURN SELF AS RESULT

次のいずれかのparseファンクションを使用して、JSON_ARRAY_Tインスタンスを作成できます。

STATIC FUNCTION parse(json VARCHAR2) RETURN JSON_ARRAY_T
STATIC FUNCTION parse(json CLOB)     RETURN JSON_ARRAY_T
STATIC FUNCTION parse(json BLOB)     RETURN JSON_ARRAY_T

また、次のいずれかのコンストラクタを使用して、JSON_ARRAY_Tインスタンスを作成することもできます。

CONSTRUCTOR FUNCTION JSON_Array_T(jsn VARCHAR2) RETURN SELF AS RESULT
CONSTRUCTOR FUNCTION JSON_Array_T(jsn CLOB) RETURN SELF AS RESULT
CONSTRUCTOR FUNCTION JSON_Array_T(jsn BLOB) RETURN SELF AS RESULT
CONSTRUCTOR FUNCTION JSON_Array_T(e JSON_ELEMENT_T) RETURN SELF AS RESULT

UTF8でエンコードされたJSONのみがBLOBとして渡されます。

parseファンクションは、入力としてJSON文字列を取り、JSONデータの内部表現を設定します。提供された入力が有効なJSONでない場合、エラー・メッセージが生成されます。入力はオブジェクトでなくJSON配列を指定する必要があります。

取得のファンクションおよびプロシージャ

次のファンクションおよびプロシージャを使用すると、JSON配列の値を取得できます。

MEMBER FUNCTION get(pos NUMBER)           RETURN JSON_ELEMENT_T
MEMBER FUNCTION get_String(pos NUMBER)    RETURN VARCHAR2
MEMBER FUNCTION get_Number(pos NUMBER)    RETURN NUMBER
MEMBER FUNCTION get_Date(pos NUMBER)      RETURN DATE
MEMBER FUNCTION get_Timestamp(pos NUMBER) RETURN TIMESTAMP
MEMBER FUNCTION get_Boolean(pos NUMBER)   RETURN BOOLEAN
MEMBER FUNCTION get_Clob(pos NUMBER)      RETURN CLOB
MEMBER FUNCTION get_Blob(pos NUMBER)      RETURN BLOB

MEMBER PROCEDURE get_Clob(pos NUMBER, c IN OUT CLOB)
MEMBER PROCEDURE get_Blob(pos NUMBER, c IN OUT BLOB)

ノート:

  • getファンクションには参照セマンティクスがあります。つまり、戻されたJSON_ELEMENT_Tが変更されると、包含するJSON_ELEMENT_Tも変更されます。

  • GET_STRINGファンクションは、まだ文字列でない値を文字列に変換します。IS_STRINGがfalseを戻した場合でも、このファンクションはnullでない値を戻します。

  • すべてのgetファンクションは、可能な場合に変換を実行します。変換が可能でない場合、ON_ERRORの設定値に応じてエラーが生成されることがあります。

GET_CLOBおよびGET_BLOBプロシージャは、CLOBまたはBLOBを入力として受け入れます。これによって、シリアライズの宛先として使用されるLOBを提供できます。たとえば、EMPTY_LOBを提供できます。このかわりにGET_CLOBファンクションを使用すると、新しいCLOBが暗黙的に作成されます。入力のLOBはNULLにできません。最初にBLOBまたはCLOBを作成しない場合は、GET_CLOBまたはGET_BLOBファンクションを使用できます。これらのファンクションはパラメータを取らずに、一時的なLOBを生成します。

GET_BLOBは、UTF8形式へのシリアライズのみを行います。

設定のプロシージャ

次のプロシージャを使用すると、JSON配列内の指定した位置に値を設定できます。これらのプロシージャでは、上書きがリクエストされないかぎり、指定された位置で(上書きではなく)挿入が行われます。

MEMBER PROCEDURE put(pos NUMBER, value VARCHAR2, overwrite BOOLEAN DEFAULT FALSE)
MEMBER PROCEDURE put(pos NUMBER, value NUMBER, overwrite BOOLEAN DEFAULT FALSE)
MEMBER PROCEDURE put(pos NUMBER, value BOOLEAN, overwrite BOOLEAN DEFAULT FALSE)
MEMBER PROCEDURE put(pos NUMBER, value JSON_ELEMENT_T, overwrite BOOLEAN DEFAULT FALSE)
MEMBER PROCEDURE put(pos NUMBER, value DATE, overwrite BOOLEAN DEFAULT FALSE) 
MEMBER PROCEDURE put(pos NUMBER, value TIMESTAMP, overwrite BOOLEAN DEFAULT FALSE)
MEMBER PROCEDURE put_Null(pos NUMBER, overwrite BOOLEAN DEFAULT FALSE)

次のプロシージャは、指定された値をJSON配列の末尾に追加します。

MEMBER PROCEDURE append(value JSON_ELEMENT_T)
MEMBER PROCEDURE append(value VARCHAR2)
MEMBER PROCEDURE append(value NUMBER)
MEMBER PROCEDURE append(value BOOLEAN)
MEMBER PROCEDURE append(value DATE)
MEMBER PROCEDURE append(value TIMESTAMP)
MEMBER PROCEDURE append_Null

イントロスペクションのファンクション

イントロスぺクションを行うと、JSON配列を変更することなくJSON配列のプロパティを検出できます。

MEMBER FUNCTION get_Type(pos NUMBER) RETURN VARCHAR2

変更のプロシージャ

次のプロシージャを使用すると、JSON配列内の指定した位置にある値を削除できます。

MEMBER PROCEDURE remove(pos NUMBER)

Cloneファンクション

このファンクションは、JSON配列のコピーを作成します。参照セマンティクスは値セマンティクスに変更されます。

MEMBER FUNCTION clone RETURN JSON_ARRAY_T

285.4 JSON_SCALAR_Tオブジェクト・タイプ

JSON_SCALAR_Tは、JSON_ELEMENT_Tオブジェクト・タイプのサブタイプです。

説明

JSON_SCALAR_Tインスタンスは、1つのスカラー値(たとえば、文字列fred、数値1など)を取得します。このタイプには、JSON_ELEMENT_Tから継承されたもの以外のファンクションまたはプロシージャはありません。このタイプのインスタンスを直接作成することはできません。

285.5 JSON_KEY_LISTタイプ

JSON_KEY_LISTは、VARCHAR2(4000)のVARRAYです。

説明

このタイプは、JSON_OBJECT_Tオブジェクト・タイプget_Keysファンクションによって使用されます。