13.2 JSON_TRANSFORM操作(代入など)

Oracle SQLファンクションjson_transformは、その入力JSONデータのコピーを変更し、変更した結果を返します。

ノート:

ファンクションjson_transformは、一時データに対して作用します。つまり、その入力データのコピーに対して作用します。その元の入力データは変更されません。これは、その一時データを、その引数による操作すべてで更新して返します。永続データを更新するには、SQL UPDATE文内でjson_transformを使用する必要があります。

定義:

指定されたjson_transform操作により、その演算子が、操作の入力データ(オペランドと呼ばれる) (これはこのファンクションの入力データ(コピーされたもの)の一部)に適用されて、それが変更されます。

たとえば、このjson_transform呼出しでは、このファンクションへの入力データは{"a":1, "b":2}であり、演算子REMOVEである単一の操作があります。この操作への入力データ(つまり、オペランド)は、パス式$.aで対象となっている入力データ(コピーされたもの)の一部です。この操作により、フィールドa (つまり、メンバー"a":1)がその入力データから削除されます。

json_transform({"a":1, "b":2}, REMOVE '$.a')

結果 — 変更された入力データ:

{"b":2}

操作の結果は、入力データ(コピーされたもの)の、更新済の新しい状態であり、次の操作の開始点として使用されます。このjson_transformの呼出しには1つの操作しかないため、その操作結果は、このファンクションの戻り値でもあります。

演算子によって、それらのオペランドに対する作用は異なります。前述のREMOVE操作では、アクションは、入力データからのオペランドの削除です。

指定されたjson_transform操作の結果は、その対象となっているJSONデータが変更されたものです。ファンクションjson_transformの戻り値は、その入力データのコピーが、そのすべての操作によって変更されたものです。これは必ずJSONデータであり、その入力と同じSQL型(JSON型、またはVARCHAR2などのテキスト型)です。ファンクションjson_transformとその操作では、JSONデータがJSONデータに変換されます。

定義:

json_transformのほとんどの演算子は代入演算子です。つまり、それらによってオペランドに新しい値が代入されます。代入される値は、必ずJSON値です。

代入構文は、LHS = RHSです。ここでのLHSは左辺を、RHSは右辺を意味します。脚注1

演算子によってRHS式が評価されてから、結果となる値(または一連の値)を使用してオペランドが処理されます。演算子によってLHSとRHSの使用方法は異なります。

LHSは、通常は、json_transformの入力データ(これは最初にその先頭の引数からコピーされる)の現在の状態を対象としたSQL/JSONパス式です。演算子SETの場合(これのみ)、LHSは、値がRHS値に設定される(標準的な代入) SQL/JSON変数にすることもできます。

SQL/JSONパス式は、多くの場合、一致するデータを取得するために問合せまたは存在チェック(json_exists)で使用されます。ただし、json_transformLHSで使用される場合は、パス式により、新しい値が配置される場所が特定されます。

この意味で、LHSのパス式は、汎用化されたパターン一致/破棄変数の役割を果たすと言えます。これは複雑なプレースホルダであり、更新する、入力データの特定の部分を示します。

たとえば、次のコード内の最初のSET操作では、そのオペランド(入力配列aの2番目の要素)が5に変更されて、aの値が[ 1,5 ]になります。次に、2番目のSET操作では、そのオペランド(更新されたa値の最初の要素)が3に変更されて、aの値が[ 3,5 ]になります。

json_transform({"a":[ 1,2 ]},
               SET '$.a[1]' = 5,
               SET '$.a[0]' = 3)

結果 — 変更された入力データ:

{"a":[ 3,5 ]}

次のコードは似ており同じ結果になりますが、ここでの2番目のSET操作では、その2番目の要素(a[1])の現在の値を使用して、最初のa要素(a[0])の新しい値が計算されます。操作の入力データの状態は、必ず、前の操作によってもたらされた状態です。

json_transform({"a":[ 1,2 ]},
               SET '$.a[1]' = 5,
               SET '$.a[0]' = a[1] - 2)

結果 — 変更された入力データ:

{"a":[ 3,5 ]}

RHSはある種の式であり、これを評価すると、1つ以上のJSON値(LHSデータを更新するためになんらかの方法で使用される)が生成されます。詳細は、「JSON_TRANSFORMの右辺(RHS)のパス式」を参照してください。

ノート:

代入のRHS (右辺)は、次のいずれかです:

  • SQL式 — その値が使用されます。例13-37を参照してください。

  • キーワードPATHの後に、一重引用符(')で囲まれたSQL/JSONパス式が続きます。脚注2 その対象となっているデータが、使用される値です。

json_transform操作の結果は、必ずJSONデータです。RHSがSQL式である場合、その値は、「SQL/JSON生成関数の入力値の処理」で示すように、暗黙的にJSON値に変換されます。

2つのSET操作がある前述の例では、各操作のRHSはSQL式であり、その値はSQL数値で、それはJSON数値として解釈されます。

次のSET操作では、オペランドは、LHSのパス式'$.a'によって指定されています。オペランドの更新に使用される値は、RHSのSQL式'z20' (リテラルSQL文字列)によって指定されており、その値はJSON文字列として解釈されます。

SET '$.a' = 'z20'

次のSET操作では、RHSのSQL式(リテラル文字列)がコンストラクタJSONでラップされており、その文字列からJSON配列が生成されます。

SET '$.a' = JSON('[ 3,1,4 ]')

結果 — 変更された入力データ:

{"a":[ 3,1,4 ]}

コンストラクタJSONが使用されなかった場合、結果は{"a":"[ 3,1,4 ]"}になります。フィールドaの値は、配列ではなくJSON文字列になります。

次のコードでは、SET操作のRHSで、配列aの2番目の要素が対象となっているパス式($a[1])が使用されています。この操作により、フィールドaが更新されて、その配列値が配列の2番目の要素(2)に置き換えられます。

json_transform({"a":[ 1,2 ]},
               SET '$.a' = PATH '$.a[1]')

結果 — 変更された入力データ:

{"a":2}

次のコードでは、最初のSET操作により、変数$varが、配列aの2番目の要素(2)に3を掛けた(*)値に設定されます。次に、2番目の操作により、配列aの1つ目の要素が、その変数の値に設定されます。

json_transform({"a":[ 1,2 ]},
               SET '$var' = PATH '$.a[1] * 3',
               SET '$.a[0]' = $var)

結果 — 変更された入力データ:

{"a":[ 6,2 ]}

ノート:

代入のRHS式が、JSONであると認識されないSQLデータに評価される場合は、次のどちらかの方法でそれをJSONデータに変換できます。(1)RHS式の後にキーワードFORMAT JSONを続けるか、(2)JSONコンストラクタ(そのデータ型をJSONに変換する)を使用してそれをラップします。

これにより、テキストSQLデータがJSONとして解析されます。たとえば、これにより、SQL文字列'[1,2]'はJSON配列[1,2]に変換されます。

コンストラクタJSONを使用するには、データベース初期化パラメータcompatible20以上である必要があります。



脚注の凡例

脚注1: 指定された演算子では、代入が必ず実行されるか決して実行されないかのどちらかです。たとえば、REMOVEでは決して実行されません(前述の例では、LHS = RHS構文はありません)。
脚注2: RHSにSQL式とパス式が両方含まれている場合は、エラーが発生します。