15 SQL/JSONパス式
Oracle Databaseでは、SQL/JSONパス式を使用したJSONデータへのSQLアクセスが提供されます。
- SQL/JSONパス式の概要
Oracle Databaseでは、SQL/JSONパス式を使用したJSONデータへのSQLアクセスが提供されます。 - SQL/JSONパス式の構文
SQL/JSONパス式は、パスの部分を選択するためにSQL/JSONファンクションおよび条件によってJSONデータと照合されます。パス式にはワイルドカードおよび配列範囲を使用できます。照合では大文字/小文字が区別されます。 - SQL/JSONパス式の項目メソッド
SQL/JSONパス式で使用可能なOracle項目メソッドについて説明します。 - ISO 8601の日時のサポート
国際標準化機構(ISO)の標準8601は、日付と時間を表すために国際的に受け入れられている方法について説明しています。Oracle Databaseでは、ISO 8601の日付と時刻の形式の多くをサポートしています。 - 比較における型
SQL/JSONパス式のフィルタ条件における比較では、コンパイル時に静的に型が指定されます。比較のオペランドの有効な型が同じであると認識されない場合、型キャストでの調整が行われることがあります。
親トピック: JSONデータの問合せ
15.1 SQL/JSONパス式の概要
Oracle Databaseでは、SQL/JSONパス式を使用したJSONデータへのSQLアクセスが提供されます。
JSONは、JavaScript値の表記法です。JSONデータがデータベースに格納されている場合、XMLデータ用のXQueryまたはXPath式とある程度似たパス式を使用してこのデータを問い合せることができます。SQL/XMLでXQuery式を使用してXMLデータに対するSQLのアクセスが許可されるのと同じように、Oracle Databaseでは、SQL/JSONパス式を使用してJSONデータに対するSQLのアクセスが提供されます。
SQL/JSONパス式の構文は単純です。パス式では、この式と一致するかこの式を満たす0(ゼロ)個以上のJSON値が選択されます。
SQL/JSON条件json_exists
の場合、少なくとも1つの値が一致する場合はtrueが戻され、一致する値がない場合はfalseが戻されます。単一の値が一致した場合、この値がスカラーである場合はSQL/JSONファンクションjson_value
によってこの値が戻され、スカラーでない場合はエラーが発生します。パス式に一致する値がない場合は、json_value
によってSQL NULL
が戻されます。
SQL/JSONファンクションjson_query
は、一致する値をすべて戻します。つまり、この関数は複数の値を戻すことができます。この動作は、XQueryの場合のように値のシーケンスを戻す動作とみなすことも、複数の値を戻す動作とみなすこともできます。(ユーザーから見えるシーケンスが現れることはありません。)
どのような場合でも、パス式の照合では、パス式の各ステップを順番に照合しようとします。いずれかのステップの照合が失敗すると、後続のステップの照合は行われず、パス式の照合は失敗します。各ステップの照合が成功すると、パス式の照合は成功します。
関連項目
親トピック: SQL/JSONパス式
15.2 SQL/JSONパス式の構文
SQL/JSONパス式は、パスの部分を選択するためにSQL/JSONファンクションおよび条件によってJSONデータと照合されます。パス式にはワイルドカードおよび配列範囲を使用できます。照合では大文字/小文字が区別されます。
SQL/JSONパス式およびJSONデータをSQL/JSONファンクションまたは条件に渡します。パス式はデータに対して照合され、一致するデータが特定のSQL/JSONファンクションまたは条件によって処理されます。この照合プロセスは、パス式が一致データを関数または条件に戻すという観点で検討することができます。
- 基本的なSQL/JSONパス式の構文
SQL/JSONパス式の基本的な構文を示します。これは、コンテキスト項目記号($
)とその後のゼロ個以上のオブジェクト、配列および子孫ステップで構成されます。それぞれの後にフィルタ式を続けることができ、オプションでファンクション・ステップを指定できます。例を示します。 - SQL/JSONパス式の構文の緩和
暗黙的な配列のラップおよびアンラップを可能にするため、SQL/JSONパス式の基本的な構文は緩和されています。これは、データが発展して特定のJSON値のかわりにこのような値の配列が使用される(またはこの逆)場合、コード内のパス式を変更する必要がないことを意味します。例を示します。
親トピック: SQL/JSONパス式
15.2.1 基本的なSQL/JSONパス式の構文
SQL/JSONパス式の基本的な構文を示します。これは、コンテキスト項目記号($
)とその後のゼロ個以上のオブジェクト、配列および子孫ステップで構成されます。それぞれの後にフィルタ式を続けることができ、オプションでファンクション・ステップを指定できます。例を示します。
ただし、この基本的な構文は、非配列パターンに対する配列の照合および配列パターンに対する非配列の照合の緩和によって拡張されます。SQL/JSONパス式の構文の緩和を参照してください。
SQL/JSONパス式に対するデータの照合では、大/小文字が区別されます。
-
SQL/JSONの基本的なパス式(ここでは単にパス式とも呼びます)は、絶対パス式または相対パス式です。
-
絶対パス式は、パス式のコンテキスト項目(つまり、照合するJSONデータ)を表すドル記号(
$
)から始まります。このデータは、SQL/JSONファンクションに引数として渡されたSQL式の評価結果です。ドル記号の後にゼロ個以上の非ファンクション・ステップが続き、その後にオプションのファンクション・ステップが続きます。 -
相対パス式は、アット・マーク(
@
)の後にゼロ個以上の非ファンクション・ステップが続き、その後にオプションのファンクション・ステップが続く形式です。ドル記号($
)のかわりにアット・マークを使用する点を除き、絶対パス式と同じ構文になります。相対パス式はフィルタ式(フィルタと短縮される)内で使用されます。アット・マークは、パス式のカレント・フィルタ項目(相対パス式を含むフィルタに先行する(周囲の)パス式の部分に一致するJSONデータ)を表します。相対パス式は、絶対パス式がコンテキスト項目に対して照合されるのと同じように、カレント・フィルタ項目に対して照合されます。
-
非ファンクション・ステップは、オブジェクト・ステップ、配列ステップまたは子孫ステップの後にオプションのフィルタ式が続く形式です。
-
単一のファンクション・ステップは、基本パス式(絶対または相対)ではオプションです。このステップがあったら、これがパス式の最後のステップになります。これはピリオド(
.
) (ドットと呼ぶこともある)の後にSQL/JSON項目メソッドが続き、その後に左カッコ((
)および右カッコ()
)が続く形式です。これらのカッコの中にホワイトスペースを入れることができます(このようなホワイトスペースは重要ではありません)。項目メソッドは、同じパス式内の残りの部分、かつファンクション・ステップに先行する部分が対象とするデータに適用されます。項目メソッドは、目的のデータを変換するために使用されます。引数としてパス式に渡されたSQLファンクションまたは条件は、対象データのかわりとして変換済データを使用します。
-
オブジェクト・ステップは、ピリオド(
.
)の後にオブジェクト・フィールド名またはすべてのフィールド(の値)を表すアスタリスク (*
)ワイルドカードが続く形式です。フィールド名は空にすることができます。この場合は、""
(ホワイトスペースなし)と記述する必要があります。空でないフィールド名は、大文字または小文字の文字A-Zで始まり、このような文字または10進数字(0-9)のみを含む必要があり、それ以外の場合は、二重引用符("
)で囲む必要があります。オブジェクト・ステップは、指定されたフィールドの値を戻します。フィールドにワイルドカードが使用されている場合、すべてのフィールドの値が特に順序は指定されずに戻されます。
-
配列ステップは、左大カッコ(
[
)の後ろに、すべての配列要素を表すアスタリスク(*
)ワイルドカードまたはカンマ(,
)で区切られた1つ以上の特定の配列索引または範囲指定のどちらかが続き、その後ろに右大カッコ(]
)が付いた形式です。アスタリスクと配列索引または範囲指定の両方を使用すると、エラーが発生します。パス式では、配列に対するJavaScript変換の場合のように、配列索引付けは0を基準として行われます(0、1、2、...)。範囲指定の形式は
N
からM
です。N
とM
は配列索引であり、N
は厳密にM
未満となります。脚注1N
がM
未満ではない場合は、問合せのコンパイル時にエラーが発生します。索引または範囲指定を使用する場合、一括して指定される配列要素は、反復せずに昇順で指定する必要があり、そうでない場合はコンパイル時にエラーが発生します。たとえば、
[3, 1 to 4]
、[4, 2]
、[2, 3 to 3]
および[2, 3, 3]
のぞれぞれでエラーが発生します。最初の2つでエラーが発生するのは順序が昇順でないためで、残りの2つでエラーが発生する理由は、配列索引3
(索引付けが0を基準にしているため、4つ目の配列要素の索引になる)が繰り返されているためです。同様に、照合の結果として生じる配列値内の要素は昇順であり、反復は行われません。パス式にアスタリスクが使用される場合、すべての配列要素が配列順序で戻されます。
-
子孫ステップでは、2つの連続したピリオド(
..
)(ドット・ドットとも呼ばれる)の後にフィールド名を指定します(オブジェクト・ステップの場合と同じ構文)。これは、直前のステップ(前のステップがない場合はコンテキスト項目)と一致するオブジェクトまたは配列で、再帰的に子孫を参照します。
各子孫レベルでは、各オブジェクトおよびオブジェクトである各配列要素について、指定された名前を持つすべてのフィールドの値が収集されます。収集されたフィールド値をすべて返します。
たとえば、次の問合せとデータについて考えます。
json_query(some_json_column, '$.a..z' WITH ARRAY WRAPPER)
{ "a" : { "b" : { "z" : 1 }, "c" : [ 5, { "z" : 2 } ], "z" : 3 }, "z" : 4 }
この問合せでは
[1,2,3]
のような配列が返され、その要素は1
、2
および3
になります。ドット・ドット(..
)の直前のステップ、つまりフィールドa
内の各フィールドz
の値が収集されます。値4の最上位のフィールドz
は、フィールドa
の値内にないため一致しません。フィールド
a
の値は、子孫が参照されるオブジェクトです。-
z
というフィールドがあり、その値(3
)が収集されます。また、値がオブジェクトであるフィールドb
もあります。これは、フィールドz
の値(1
)を収集するために子孫が参照されます。 -
値が配列であるフィールド
c
もあり、この配列には、値(2
)が収集されるフィールドz
を持つオブジェクトである要素があります。
したがって、収集されるJSON値は
3
、1
および2
です。これらの値は未定義の順序で配列にラップされます。可能性のある戻り値の1つは、[1,2,3]
です。 -
-
フィルタ式(フィルタと短縮される)は、疑問符(
?
)の後カッコ(()
)で囲まれたフィルタ条件を記述します。条件が満たされるとフィルタが満たされ、trueが戻されます。 -
フィルタ条件では、その引数に述語(ブール型関数)が適用されます。次のいずれかが該当します。この例の、
cond
、cond1
およびcond2
が、フィルタ条件を表します。-
( cond )
: カッコを使用してグループ化することで、前後にあるその他のフィルタ条件から、フィルタ条件cond
を1つのユニットとして区別します。 -
cond1 && cond2
:cond1
とcond2
の論理積(and)で、両方を満たす必要があります。 -
cond1 || cond2
:cond1
およびcond2
の包含的論理和(or)で、cond1
、cond2
またはその両方を満たす必要があります。 -
! ( cond )
:cond
の否定を表し、cond
が満たされてはならないことを意味します。 -
exists (
、単純な相対パス式、)
: 対象となるデータが存在する条件。 -
比較(次のいずれか)
-
相対パス式、その後に比較述語、その後にJSONスカラー値またはSQL/JSON変数のいずれか。
-
JSONスカラー値またはSQL/JSON変数のいずれか、その後に比較述語、その後に相対パス式。
-
JSONスカラー値、その後に比較述語、その後に別のJSONスカラー値。
-
相対パス式の後に
has substring
、starts with
、like
、like_regex
またはeq_regex
が続き、その後にJSON文字列またはSQL文字列(データベース文字セットからUTF8に自動的に変換される)にバインドされているSQL/JSON変数が続きます。-
has substring
は、一致するデータ値に部分文字列として指定された文字列が含まれていることを意味します。 -
starts with
は、一致するデータ値に接頭辞として指定された文字列が含まれていることを意味します。 -
like
は、JSON文字列データ値が、SQLLIKE4
文字セット・セマンティクスを使用するSQLLIKE
パターンとして解釈される指定された文字列と一致することを意味します。パターン内のパーセント記号(%
)は、ゼロ個以上の文字に一致します。アンダースコア(_
)は1文字と一致します。ノート:
SQL
LIKE
の場合とは異なり、パス式の述語like
にはエスケープ文字がありません。また、like
パターンで文字`
、つまりグレーブ・アクセント記号(U+0060)を使用しないことをお薦めします。バッククォートやバックティックとも呼ばれるこの文字は、将来使用するために予約されています。 -
like_regex
は、JSON文字列データ値が、SQLLIKE4
文字セット・セマンティクスを使用するSQLREGEXP LIKE
正規表現パターンとして解釈される指定された文字列と一致することを意味します。like_regex
はパターン一致比較の例外です。パターンが空のJSON文字列(""
)と一致するためです。 -
eq_regex
はlike_regex
と同様ですが、次の2つの違いがあります。-
eq_regex
は、JSON文字列データ値全体に対する正規表現パターンと一致します。完全な文字列は、比較対象のパターンと一致する必要があります。like_regex
は、JSON文字列の一部がパターンと一致する場合に満たされます。 -
eq_regex
パターンが空のJSON文字列(""
)と一致しません。
-
これらのすべての述語について、空の文字列(
""
)のパターンは空の文字列のデータに一致します。また、like_regex
以外のすべてで、空でない文字列であるパターンは空の文字列のデータと一致しません。like_regex
の場合、空でないパターンは空の文字列データと一致します。 -
-
相対パス式の後に
in
が続き、その後に値リストが続きます。つまり、値が値リストにある値のいずれかになります。
比較述語は
==
、<>
、!=
<a id="fn_2" name="fn_2" href="#fn_2" onclick='footdisplay(2, "!= is an Oracle alias for the SQL/JSON standard comparison predicate <>.")'>脚注2、<
、<=
、>=
または>
です(それぞれ等しい、等しくない、未満、以下、以上、より大きい)。SQL/JSON変数は、ドル記号(
$
)の後に、json_exists
のPASSING
句内にバインドされるSQL識別子の名前が続きます。 -
- 値リストは、
(
の後に、1つ以上のスカラー値およびSQL/JSON変数をカンマ(,
)で区切ったリストが続き、その後に)
が続く形式です。
このように、フィルタ条件で使用できる述語は、
&&
、||
、!
、exists
、==
、<>
、!=
、<
、<=
、>=
、>
およびin
です。例を示します。次の基準の両方が満たされると、フィルタ条件
(a || b) && (!(c) || d < 42)
が満たされることになります。-
a
とb
のフィルタ条件のうち、少なくともいずれか1つが満たされる:(a || b)
-
フィルタ条件
c
が満たされない、は数値d
が42以下になる、またはその両方が当てはまる:(!(c) || d < 42)
比較述語
!
、&&
、||
は、この順番で優先度が高くなります。カッコは、常にグループ化を制御するために使用できます。グループ化のためのカッコを使用しないと、前述の例は
a || b && !(c) || d < 42
のようになり、次の条件の少なくともいずれか1つが満たされた場合に、この式が満たされます。-
条件
b && !(c)
が満たされる。つまり、条件b
と!(c)
がそれぞれ満たされることを意味する(つまり、条件c
は満たされない)。 -
条件
a
が満たされる。 -
条件
d < 42
が満たされる。
-
比較の少なくとも一方をSQL/JSON変数にすることはできません。比較のデフォルトの型は、非変数側の型に基づいてコンパイル時に定義されます。型指定項目メソッドを使用すると、このデフォルトを別の型でオーバーライドできます。一致するデータの型は、比較のために自動的に変換され、決定された型(デフォルトまたは項目メソッドで指定)に適合します。たとえば、$.a > 5
では5
が数値であるため、数値の比較が課され、$.a > "5"
では"5"
が文字列であるため、文字列の比較が課されます。
ヒント:
頻繁に使用する問合せの場合には、PASSING
句を使用してSQLバインド変数を定義します。これらは、パス式でSQL/JSON変数として使用されます。これにより、(変数)値の変更時に問合せの再コンパイルを回避することで、パフォーマンスが向上する可能性があります。
たとえば、この問合せは、バインド変数V1
の値をSQL/JSON変数$V1
として渡します。
SELECT po.po_document FROM j_purchaseorder po
WHERE json_exists(po.po_document,
'$.LineItems.Part?(@.UPCCode == $V1)'
PASSING '85391628927' AS "V1");
ノート:
強力な全文検索の場合は、Oracle SQLファンクションjson_textcontains
を使用します。この場合、JSON検索索引を作成する必要があります。あまり強力ではない代替方法として、JSON検索索引を作成せず、フィルタ条件に単純な文字列パターン一致のみが必要な場合は、パターン一致比較のいずれかを使用できます(has substring
、starts with
、like
、like_regex
またはeq_regex
)。
パス式の例を次に示しますが、その意味も詳述しています。
-
$
- コンテキスト項目。 -
$.friends
- コンテキスト項目オブジェクトのフィールドfriends
の値。ドル記号($
)の直後のドット(.
)は、コンテキスト項目がJSONオブジェクトであることを示します。 -
$.friends[0]
- コンテキスト項目オブジェクトのフィールドfriends
の値である配列の最初の要素であるオブジェクト。大カッコ表記法は、フィールドfriends
の値が配列であることを示します。 -
$.friends[0].name
- コンテキスト項目オブジェクトのフィールドfriends
の値である配列の最初の要素であるオブジェクトのフィールドname
の値。2番目のドット(.
)は、配列friends
の最初の要素が(フィールドname
を持つ)オブジェクトであることを示します。 -
$.friends[*].name
- コンテキスト項目オブジェクトのフィールドfriends
の値である配列の各オブジェクトのフィールドname
の値。 -
$.*[*].name
- コンテキスト項目オブジェクトのフィールドの配列値に含まれる各オブジェクトのフィールドname
の値。 -
$.friends[3, 8 to 10, 12]
– 配列friends
(コンテキスト項目オブジェクトのフィールド)の4番目、9番目から11番目、13番目の要素です。要素は昇順に指定する必要があり、戻される順序は、4番目、9番目、10番目、11番目、13番目の順です。 -
$.friends[3].cars
- 配列friends
の4番目の要素であるオブジェクトのフィールドcars
の値。ドット(.
)は、4番目の要素が(フィールドcars
を持つ)オブジェクトであることを示します。 -
$.friends[3].*
- 配列friends
の4番目の要素であるオブジェクトのすべてのフィールドの値。 -
$.friends[3].cars[0].year
– 配列friends
の4番目の要素であるオブジェクトのフィールドcars
の値である配列の最初の要素であるオブジェクトのフィールドyear
の値。 -
$.friends[3].cars[0]?(@.year > 2016)
- 配列cars
(配列friends
の4番目の要素であるオブジェクトのフィールド)の最初のオブジェクト。ただし、そのフィールドyear
の値が2016よりも大きいか、2016よりも大きい数値に変換できるもの。"2017"
などのyear
値は、テストを満たす数値2017
に変換されます。"recent"
などのyear
値は、一致せず、テストに失敗します。 -
$.friends[3].cars[0]?(@.year.number() > 2016)
- 前と同じです。項目メソッドnumber()
は数値に変換できる数値または文字列値のみを許可し、その動作は数値比較述語>
によってすでに指定されています。 -
$.friends[3].cars[0]?(@.year.numberOnly() > 2016)
- 前と同じですが、year
値は数値である場合にかぎられます。項目メソッドnumberOnly()
は、year
値が文字列数字("2017"
など)である車を除外します。 -
$.friends[3]?(@.addresses.city == "San Francisco")
– 配列friends
の4番目の要素であるオブジェクト。ただし、そのaddresses
フィールドの値が、フィールドcity
の値が文字列"San Francisco"
のオブジェクトであるもの。 -
$.friends[*].addresses?(@city starts with "San ").zip
- 住所city
の名前が"San "で始まる、friends
のすべてのaddresses
の郵便番号。(この場合、フィルタは最後のパス・ステップではありません。) -
$..zip
- 任意のレベルのzip
フィールドのすべての値。 -
$.friends[3]?(@.addresses.city == "San Francisco" && @.addresses.state == "Nevada")
– 配列friends
の4番目の要素であるオブジェクト。ただし、city
が"San Francisco"
の住所に対する一致があり、state
が"Nevada"
の住所に対する一致もあるもの。ノート: 論理積になったフィルタ条件は、必ずしも同じオブジェクトに該当する必要はありません。このフィルタでは、cityがSan Franciscoのオブジェクトがあるかどうかと、stateがNevadaのオブジェクトがあるかどうかがテストされます。cityがSan FranciscoでstateがNevadaの両方を備えたオブジェクトがあるかどうかはテストされません。JSON_EXISTSでのフィルタの使用を参照してください。
-
$.friends[3].addresses?(@.city == "San Francisco" && @.state == "Nevada")
– 配列friends
の4番目の要素であるオブジェクト。ただし、そのオブジェクトに、city
の"San Francisco"
の一致と、state
の"Nevada"
の一致があるもの。前述の例とは異なり、この場合の論理積のフィルタ条件(フィールド
city
とstate
)は、同じaddresses
オブジェクトに適用されます。フィルタは、その外側にある特定のaddresses
オブジェクトに適用されます。 -
$.friends[3].addresses?(@.city == $CITY && @.state == $STATE)
- 前と同じですが、比較に使用される値はSQL/JSONの変数、$CITY
および$STATE
です。この変数値は、PASSING
句のSQLバインド変数CITY
およびSTATE
によって指定されます。比較に変数を使用すると、問合せの再コンパイルが回避されることでパフォーマンスが向上します。
関連項目
関連項目:
-
ISO 8601 (ISOの日付形式の詳細)
-
SQL条件
REGEXP LIKE
の詳細は、Oracle Database SQL言語リファレンスを参照してください -
SQL条件
LIKE
およびLIKE4
文字セット・セマンティクスの詳細は、Oracle Database SQL言語リファレンスを参照してください
親トピック: SQL/JSONパス式の構文
15.2.2 SQL/JSONパス式の構文の緩和
暗黙的な配列のラップおよびアンラップを可能にするため、SQL/JSONパス式の基本的な構文は緩和されています。これは、データが発展して特定のJSON値のかわりにこのような値の配列が使用される(またはこの逆)場合、コード内のパス式を変更する必要がないことを意味します。例を示します。
SQL/JSONパス式の基本的な構文では、SQL/JSONパス式の基本的な構文を定義しています。サポートされている実際のパス式の構文では、この定義を次のように緩和します。
-
パス式のステップが配列を対象としている(予測している)が、実際のデータは配列を示していない場合、データは暗黙的に配列にラップされます。
-
パス式のステップが非配列を対象としている(予測している)が、実際のデータは配列を示している場合、配列タは暗黙的にアンラップされます。
この緩和により、次の省略が可能になります。すなわち、[*]
は、オブジェクト・アクセッサ.
の前にあり、オブジェクト・フィールド名が後ろに続く場合は常に省略でき、本質的に何の変更も行われません。この逆もまた真です。[*]
は、オブジェクト・アクセッサ.
の前に常に挿入でき、本質的に何の変更も行われません。
つまり、特定のオブジェクトの配列の各要素のフィールドprop
の値を表すオブジェクト・ステップ[*].
prop
は.prop
として省略でき、単一オブジェクトのprop
値を表すかのように見えるオブジェクト・ステップ.prop
は、オブジェクト・アクセッサが適用された配列の各要素のprop
値も表します。
これは重要な機能です。なぜなら、データが発展して特定のJSON値のかわりにこのような値の配列が使用される(またはこの逆)場合、コード内のパス式を変更する必要がないからです。
たとえば、フィールドtype
およびnumber
を伴う単一オブジェクトが値であるフィールドPhone
を持つオブジェクトがデータにもともと含まれるときに、このデータが発展して電話の配列を表す場合、単一の電話番号と一致するパス式$.Phone.number
を引き続き使用できます。パス式$.Phone.number
は、番号を選択して単一の電話オブジェクトと一致することも、各番号を選択して電話オブジェクトの配列と一致することもできます。
同様に、データに両方の種類の表現が混在する(単一の電話オブジェクトを使用するデータ・エントリ、および電話オブジェクトの配列を使用するエントリ、または両方を使用するエントリさえも存在する)場合、同じパス式を使用して、これらの異なる種類のエントリの電話情報にアクセスできます。
次に、SQL/JSONパス式の基本的な構文の項のパス式の例を、相当する式の説明とともに示します。
-
$.friends
– 次のいずれかのフィールドfriends
の値。-
(単一の)コンテキスト項目オブジェクト。
-
(
$[*].friends
に相当)コンテキスト項目配列内の各オブジェクト。
-
-
$.friends[0].name
- 次のオブジェクトのいずれかのフィールドname
の値。-
コンテキスト項目オブジェクトのフィールド
friends
の値である配列の最初の要素。 -
(
$.friends.name
に相当)コンテキスト項目オブジェクトのフィールドfriends
の値。 -
(
$[*].friends.name
に相当)コンテキスト項目配列の各オブジェクトのフィールドfriends
の値。 -
(
$[*].friends[0].name
に相当)コンテキスト項目配列の各オブジェクトのフィールドfriends
の値である各配列の最初の要素。
コンテキスト項目はオブジェクトでもオブジェクトの配列でもかまいません。後者の場合、配列内の各オブジェクトはフィールド
friends
について照合されます。フィールド
friends
の値はオブジェクトでもオブジェクトの配列でもかまいません。後者の場合、配列内の最初のオブジェクトが使用されます。 -
-
$.*[*].name
– 次のオブジェクトのいずれかのフィールドname
の値。-
コンテキスト項目オブジェクトのフィールドの配列値の要素。
-
(
$.*.name
に相当)コンテキスト項目オブジェクトのフィールドの値。 -
(
$[*].*.name
に相当)コンテキスト項目配列のオブジェクトのフィールドの値。 -
(
$[*].*[*].name
に相当)コンテキスト項目配列のオブジェクトのフィールドの配列値の各オブジェクト。
-
関連項目
親トピック: SQL/JSONパス式の構文
15.3 SQL/JSONパス式の項目メソッド
SQL/JSONパス式で使用できるOracle項目メソッドについて説明します。
項目メソッドは、このメソッドで終了するパス式(の残り)が対象とするJSONデータに適用されます。メソッドは、目的のデータを変換するために使用されます。パス式に渡されたSQLファンクションまたは条件は、対象データのかわりとして変換済データを使用します。項目メソッドのアプリケーションがフィルタとして機能し、この結果セットから対象データを削除する場合があります。
引数の型が間違っているなどのなんらかの理由で項目メソッドの変換が失敗した場合、パスは照合されず(参照データがない状態)、エラーは発生しません。このことは、特に、パス式が渡されるSQL/JSONファンクションまたは条件のエラー句でこのようなエラーが処理されないことを意味します。
配列への項目メソッドの適用
項目メソッドsize()
およびtype()
を除き、項目メソッドが配列を対象とする場合、このメソッドは配列自体ではなく各配列要素に適用されます。たとえば、$.a.method()
は、項目メソッドmethod()
を配列a
の各項目に適用して変換し、配列のかわりに使用します。(このことは、実質的に、オブジェクト・ステップに対して非配列が想定される場合の配列の暗黙のアンラップと同様です。)一致の結果セットには、対象の配列ではなく、変換された配列要素が含まれます。
json_query
またはjson_query
セマンティクスを持つjson_table
列式に対して、ラッパー句を使用すると変換されたすべての配列要素値を配列として取得できます。たとえば、次のような問合せになります。
SELECT json_query('["alpha", 42, "10.4"]', '$[*].stringOnly()' WITH ARRAY WRAPPER) FROM dual;
配列["alpha", "10.4"]
が返されます(VARCHAR2
値として)。
これに関して、項目メソッドsize()
およびtype()
は例外です。配列に適用する場合、これらの項目メソッドは、その要素を処理するかわりに配列をそのまま扱います。たとえば:
SELECT json_value('[19, "Oracle", {"a":1},[1,2,3]]', '$.type()') FROM dual;
単一のVARCHAR2
値'array'
が返されます。
項目メソッドの説明
次の項目メソッドの説明では、対象となるJSON値が特定のSQLデータ型の値として解釈される場合があると記述されています。これは、そのSQLデータ型を含むjson_value
RETURNING
句で制御されたかのように処理されることを意味します。
たとえば、項目メソッドstring()
は句RETURNING VARCHAR2(4000)
を含むjson_value
と同じようにターゲットを解釈します。ブール値はstring()
によって"true"
または"false"
として扱われ、null
値は"null"
として扱われ、数値は正準な文字列形式で表されます。
一部の項目メソッドは、対象のJSONデータをSQLのデータ型であるかのように解釈するため、RETURNING
句のかわりにjson_value
とともに使用できます。また、列型を指定するかわりにjson_table
とともに使用できます。つまり、項目メソッドは、抽出されたJSONデータにSQLデータ型を指定するために使用できます。
このような項目メソッドをjson_value
のRETURNING
句またはjson_table
の列型指定とともに使用することもできます。抽出されたJSONデータに使用するSQLデータ型が項目メソッドおよびjson_value
RETURNING
句またはjson_table
列タイプの両方によって制御されている場合はどうなりますか。
-
2つのデータ型に互換性がある場合、
RETURNING
句または列のデータ型が使用されます。これらのために、VARCHAR2
はVARCHAR2
とCLOB
の両方と互換性があります。 -
これらのデータ型に互換性がない場合、静的コンパイル時にエラーが発生します。
表15-1 型変換項目メソッドとRETURNINGの型の互換性
項目メソッド | 互換性のあるRETURNING句のデータ型 |
---|---|
string() またはstringOnly() |
VARCHAR2 またはCLOB (string() がJSON null 値に対してSQL NULL を返すことを除く)
|
number() またはnumberOnly() |
NUMBER |
date() |
DATE |
timestamp() |
TIMESTAMP |
boolean() またはbooleanOnly() |
VARCHAR2 |
RETURNING
句または列指定を使用すると、文字データの長さ、および数値データの精度とスケールを指定できます。これにより、対象データの比較のために項目メソッドで指定されるものよりも、抽出に対して正確にSQLデータ型を割り当てることができます。
たとえば、項目メソッドstring()
およびRETURNING VARCHAR2(150)
を使用する場合、戻されるデータのデータ型はVARCHAR2(150)
で、VARCHAR2(4000)
ではありません。
名前に"only"が含まれるデータ型の変換メソッドは、"only"が含まれない名前の対応するメソッドと同じです。前者は、特定の型であるJSON値(number
など)のみを関連のSQLデータ型(NUMBER
など)に変換する点が異なります。名前に"only"が含まれないメソッドは、任意のJSON値を指定したSQLデータ型に変換できます。("only"メソッドで配列を対象とする場合、変換は通常どおり、各配列要素に適用されます。)
-
abs()
: 対象となるJSONの数値の絶対値。SQLファンクションABS
の使用に対応します。 -
boolean()
: 対象となるJSON値のSQLVARCHAR2(20)
の解釈。 -
booleanOnly()
: JSONのブール値である場合、対象となるJSONデータのSQLVARCHAR2(20)
の解釈。それ以外の場合、一致はありません。フィルタとして機能し、JSONのブール値の場合のみ一致が可能です。 -
ceiling()
: 最も近い整数に切り上げられた対象となるJSONの数値。SQLファンクションCEIL
の使用に対応します。 -
date()
: 対象となるJSON文字列のSQLの日付の解釈。対象となる文字列データは、サポートされているISO 8601形式のいずれかである必要があります。それ以外の場合、一致はありません。 -
double()
: 対象となるJSON文字列または数値のSQLBINARY_DOUBLE
での解釈。 -
floor()
: 最も近い整数に切り捨てられた対象となるJSONの数値。SQLファンクションFLOOR
の使用に対応します。 -
length()
: 対象となるJSON文字列内の、SQLNUMBER
として解釈される文字数。 -
lower()
: 対象となるJSON文字列内の文字に対応する小文字の文字列。 -
number()
: 対象となるJSON文字列または数値のSQLNUMBER
の解釈。 -
numberOnly()
: JSONのブール値である場合、対象となるJSONデータのSQLNUMBER
の解釈。それ以外の場合、一致はありません。フィルタとして機能し、JSONの数値の場合のみ一致が可能です。 -
size()
: 配列内の要素数。あるいはスカラーまたはオブジェクトの場合は1。この項目メソッドは、json_query
、json_value
およびjson_table
とともに使用できます。配列のデータに適用される場合、配列要素に対する暗黙的な反復は発生しません。結果の値は配列要素の数に一致します。(暗黙的反復のルールに対する例外。) -
string()
: 対象となるスカラーのJSON値のSQLVARCHAR2(4000)
の解釈。 -
stringOnly()
: JSON文字列である場合、対象となるスカラーJSON値のSQLVARCHAR2(4000)
の解釈。それ以外の場合、一致はありません。フィルタとして機能し、JSON文字列の場合のみ一致が可能です。 -
timestamp()
: 対象となるJSON文字列のSQLTIMESTAMP
の解釈。対象となる文字列データは、サポートされているISO 8601形式のいずれかである必要があります。それ以外の場合、一致はありません。<a id="fn_3" name="fn_3" href="#fn_3" onclick='footdisplay(3, "Applying item method timestamp() to a supported ISO 8601 string <ISO-STRING> has the effect of SQL sys_extract_utc(to_utc_timestamp_tz(脚注3 -
type()
: SQLVARCHAR2(20)
値として解釈される、対象となるデータのJSONデータ型の名前。この項目メソッドは、json_query
、json_value
およびjson_table
とともに使用できます。配列のデータに適用される場合、配列要素に対する暗黙的な反復は発生しません。結果の値は"array"
となります。(暗黙的反復のルールに対する例外。)-
null
の値の場合、"null"
。 -
true
またはfalse
の値の場合、"boolean"
。 -
数値の場合、
"number"
。 -
文字列の場合、
"string"
。 -
配列の場合、
"array"
。 -
オブジェクトの場合、
"object"
。
-
-
upper()
: 対象となるJSON文字列内の文字に対応する大文字の文字列。
項目メソッドboolean()
、booleanOnly()
、date()
、length()
、lower()
、number()
、numberOnly()
、string()
、stringOnly()
、timestamp()
およびupper()
は、SQL/JSON標準に対するOracleの拡張機能です。その他の項目メソッドのabs()
、ceiling()
、double()
、floor()
、size()
およびtype()
は標準に含まれています。
15.4 ISO 8601日付および時間のサポート
国際標準化機構(ISO)の標準8601は、日付と時間を表すために国際的に受け入れられている方法について説明しています。Oracle Databaseでは、ISO 8601の日付と時刻の形式の多くをサポートしています。
国際標準化機構(ISO)の標準8601は、日付と時間を表すために国際的に受け入れられている方法について説明しています。適切なOracle Databaseの日付と時刻の値として、最も一般的なISO 8601日時形式の文字列を操作できます。サポートされているISO 8601形式は、基本的に数字のみで言語に依存しない明確な形式です。
これは日付および時間に許可されている構文です。
-
日付(のみ):
YYYY-MM-DD
-
日付と時刻:
YYYY-MM-DDThh:mm:ss[.s[s[s[s[s[s]]]]][Z|(+|-)hh:mm]
各要素の意味は次のとおりです。
-
YYYY
は、4桁の10進数で年を指定します。 -
MM
は、00
から12
までの2桁の10進数で月を指定します。 -
DD
は、00
から31
までの2桁の10進数で日を指定します。 -
hh
は、00
から23
までの2桁の10進数で時間を指定します。 -
mm
は、00
から59
までの2桁の10進数で分を指定します。 -
ss[.s[s[s[s[s]]]]]
は、00
から59
までの2桁の10進数で秒を指定します。オプションで、小数点を1から6桁の10進数で追加します(秒の端数部分を表します)。 -
Z
は、UTC時間(タイムゾーン0)を指定します。(–00:00
ではなく、+00:00
で指定することもできます。) -
(+|-)hh:mm
は、UTCとの差異でとタイムゾーンを指定します。(+
または–
のいずれか1つを指定する必要があります。)
時間の値の場合、タイムゾーン部分はオプションです。これが指定されていない場合、UTC時間が使用されます。
他のISO 8601の日時構文はサポートされていません。具体的には、次のとおりです。
-
ハイフンで始まるマイナスの日付(例:
–2018–10–26T21:32:52
) (BCE1年より前の日付)はサポートされていません。 -
ハイフンおよびコロンの区切り文字が必要です。いわゆる基本形式
YYYYMMDDThhmmss
はサポートされていません。 -
序数の日付(年と通算日、カレンダ週と曜日番号)はサポートされていません。
-
年に4桁より大きい桁数を使用することは、サポートされていません。
サポートされている日付および時間は、次のとおりです。
-
2018–10–26T21:32:52
-
2018-10-26T21:32:52+02:00
-
2018-10-26T19:32:52Z
-
2018-10-26T19:32:52+00:00
-
2018-10-26T21:32:52.12679
サポートされていない日付と時間は、次のとおりです。
-
2018-10-26T21:32
(時間が指定された場合、そのすべての部分が存在する必要があります) -
2018-10-26T25:32:52+02:00
(時間部分は25で、範囲外です) -
18-10-26T21:32
(年がすべて指定されていません)
関連項目:
親トピック: SQL/JSONパス式
15.5 比較における型
SQL/JSONパス式のフィルタ条件での比較は、コンパイル時に静的に型を指定します。比較のオペランドの有効な型が同じであると認識されない場合、型キャストでの調整が行われることがあります。
SQL/JSONパス式がJSONデータを対象としているため、比較のオペランドはJSON値です。JSON値の型の比較は単純です。JSONのデータ型である文字列、数値、null、オブジェクトおよび配列は、相互に排他的であり、比較できません。
ただし、比較オペランドはSQLデータ型の値として解釈(基本的にキャスト)されることがあります。たとえば、number()
などの一部の項目メソッドが使用されている場合などです。この項は、このような有効値の型チェックに対応しています。
onlyが付く項目メソッドのいずれかを使用して、明示的にこのような型キャストを回避できます。たとえば、メソッドnumberOnly()
を使用すると、数値への暗黙的な型キャストが回避されます。
SQLは静的に型を指定する言語のため、型はコンパイル時に決定されます。同じことがSQL/JSONパス式に適用され、特にフィルタ条件での比較にも適用されます。これは、評価方法に関係なく(索引、マテリアライズド・ビューおよびインメモリー・スキャンなどの機能を使用するかどうかに関係なく)、問合せに対して同じ結果が得られるという意味です。
これを実現するには、次のようにします。
-
両方のオペランドの型が認識されており、同じである場合、型チェックが実行されます。
-
両方のオペランドの型が不明の場合、コンパイル時にエラーが発生します。
-
1つのオペランドの型が認識されていて、もう一方の型が不明な場合、後者のオペランドは前者の型にキャストされます。
たとえば、
$.a?(@.b.c == 3)
で$a.b.c
の型がコンパイル時に不明とします。パス式は、$.a?(@.b.c.number() == 3)
としてコンパイルされます。実行時に、$a.b.c
と一致するデータの数値へのキャストが試行されます。文字列値"3"
は数値3
にキャストされ、比較が実行されます。脚注4 -
両方のオペランドの型は認識されており、これらが異なっている場合、一方の型のもう一方の型へのキャストが試行されます。詳細を次に示します。
次の組合せで使用される比較オペランドは調整されず、コンパイル時のエラーが発生します。
-
double型以外の非数値型と比較される数値。
-
数値以外の非double型と比較されるdouble型。
-
double型と比較される文字列。
-
非ブール型と比較されるブール値。
'true'
または'false'
の文字列値(または'tRUe'
などの大/小文字のバリアント)との比較の場合を除きます。 -
文字列がサポートされているISO 8601形式である場合を除く、文字列と比較される日付またはタイムスタンプ。
-
文字列以外の非日付型と比較される日付。
-
文字列以外の非タイムスタンプ型と比較されるタイムスタンプ(タイムゾーンがある場合とない場合)。
-
JSON
null
以外の任意の型と比較されるJSONnull
。
次の組合せで使用される比較オペランドの調整の試行が、型キャストによって行われます。他のオペランドと互換性のある型にするために、型キャストの項目メソッドがオペランドのいずれかに暗黙的に適用されます。
-
doubleと比較される数値 —
double()
は暗黙的に通知に適用され、これをdouble値にします。 -
ブールと比較される
'true'
または'false'
の文字列値(または'tRUe'
などの大/小文字のバリアント) —boolean()
は暗黙的に文字列に適用され、これをブール値にします。 -
日付と比較されるサポートされているISO 8601形式の文字列 —
date()
は暗黙的に文字列に適用され、これを日付値にします。(存在する任意のタイムゾーン・コンポーネントは削除されます。) -
タイムゾーンが含まれているかいないかに関係なくタイムスタンプと比較される、サポートされているISO 8601形式の文字列 —
timestamp()
は暗黙的に文字列に適用され、これをタイムスタンプ値にします。このため、UTCタイムゾーン(協定世界時、ゼロのオフセット)はデフォルトとして使用され、文字列で指定された任意のタイムゾーンを考慮します。
親トピック: SQL/JSONパス式
脚注の凡例
脚注1: 範囲指定のto
は、配列のslice演算子と非公式に呼ばれることがあります。脚注2:
!=
は、SQL/JSON標準比較述語<>
のOracle別名。脚注3: 項目メソッド
timestamp()
をサポートされているISO 8601文字列<ISO-STRING>
に適用すると、SQL sys_extract_utc(to_utc_timestamp_tz(<ISO-STRING>))
の効果があります。脚注4: ここでこのようなキャストを回避するには、項目メソッド
numberOnly()
: $.a?(@.b.c.numberOnly() == 3)
を適用します。文字列値"3"
を含むデータは一致せず、フィルタで除外されます。