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_transform
のLHSで使用される場合は、パス式により、新しい値が配置される場所が特定されます。
この意味で、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
を使用するには、データベース初期化パラメータcompatible
が20
以上である必要があります。
脚注の凡例
脚注1: 指定された演算子では、代入が必ず実行されるか決して実行されないかのどちらかです。たとえば、REMOVE
では決して実行されません(前述の例では、LHS
=
RHS
構文はありません)。脚注2: RHSにSQL式とパス式が両方含まれている場合は、エラーが発生します。