2.2 JSONデータ型
SQLデータ型JSON
とは、ネイティブ・バイナリ形式OSONを使用したJSONデータを意味します。OSONは、Oracle DatabaseサーバーとOracle Databaseクライアントの両方で問合せおよび更新を迅速に行うための、オラクル社による最適化された形式です。他のSQLデータからJSON
型インスタンスを作成できます(およびその逆に作成できます)。
JSON
型以外にJSONデータをサポートする他のSQLデータ型には、VARCHAR2
、CLOB
およびBLOB
があります。このJSON
型以外のデータは、テキストのJSONデータまたはシリアライズされたJSONデータと呼ばれます。これは解析されていない文字データです(このデータはUTF-8でエンコードされたバイトのシーケンスであるため、BLOB
インスタンスとして格納されている場合でも同様です)。
データ型JSON
を使用すると、コストのかかるテキストJSONデータの解析と再解析が回避され、問合せパフォーマンスが向上します。
テキストのJSONデータは、型コンストラクタJSON
を使用して解析することによって、JSON
型のデータに変換できます。JSON
型のデータベース列に挿入するJSONテキストは、暗黙的に解析されます。コンストラクタを明示的に使用する必要はありません。
ノート:
解析されたJSONデータは必ず、標準IETF RFC 8259、ECMA 404およびECMA 262で定義されているとおりの厳密なJSON構文になっています。具体的に述べると、JSON
型のデータが、必ず、厳密な構文になっているということです。このことは、解析されたデータが格納(永続化)されているかどうかに関係なく当てはまりまります。Oracleでは、出力時に必ずこの構文が尊重されます。(入力については、JSONデータのデフォルト構文は緩慢です。)
逆の方向の場合は、SQL/JSONファンクションjson_serialize
を使用して、JSON
型のデータをテキストのJSONデータに変換できます。JSONテキスト・データ型(VARCHAR2
、CLOB
またはBLOB
)のデータベース列に挿入するJSON
型のデータは、暗黙的にシリアライズされます。json_serialize
を明示的に使用する必要はありません。
JSON
型のデータにOracle固有のスカラーJSON型(日付など)が使用されるかどうかにかかわらず、シリアライズされたJSONデータは常にJSON標準に準拠しています。
SQL/JSON生成関数(json_object
、json_array
、json_objectagg
およびjson_arrayagg
)を使用して、JSON
型以外のデータから複雑なJSON
型のデータを作成できます。
SQL/JSONファンクションjson_scalar
を使用すると、スカラーJSON値を持つJSON
型インスタンスを作成できます。特に、Oracle固有のJSON言語型(JSON標準の一部ではない日付など)を値に使用できます。
逆の方向の場合は、SQL/JSONファンクションjson_value
を使用してJSON
型のデータに問合せを行い、SQLオブジェクト型またはコレクション型のインスタンスを返すことができます。
JSON
データ型、そのコンストラクタJSON
およびSQL/JSONファンクションjson_scalar
は、データベース初期化パラメータcompatible
が少なくとも20
の場合にのみ使用できます。それ以外の場合、それらのいずれかを使用しようとするとエラーが発生します。
_________________________________________________________
- JSONデータ型コンストラクタ
JSON
データ型コンストラクタのJSON
は、テキストのJSON値(スカラー、オブジェクトまたは配列)を入力としてを受け取って解析し、その値をJSON
型のインスタンスとして返します。また、SQL型VECTOR
、ユーザー定義のPL/SQL型またはSQL集計型のインスタンスを入力にすることもできます。 - SQL/JSONファンクションJSON_SCALAR
SQL/JSONファンクションjson_scalar
は、SQLスカラー値を入力として受け取り、対応するJSONスカラー値をJSON
型インスタンスとして返します。値には、JSON標準に含まれない日付など、Oracle固有のJSON言語型を使用できます。 - SQL/JSONファンクションJSON_SERIALIZE
SQL/JSONファンクションjson_serialize
は、入力としてJSONデータ(SQLデータ型BLOB
、CLOB
、JSON
、VARCHAR2
)を受け取り、そのテキスト表現を(BLOB
またはVARCHAR2
データとして)返します。VARCHAR2(4000)
はデフォルトの戻り型です。 - JSONコンストラクタ、JSON_SCALARおよびJSON_SERIALIZE: サマリー
JSON
データ型コンストラクタJSON
、SQL/JSONファンクションjson_scalar
およびSQL/JSONファンクションjson_serialize
間の関係について概要を示します。 - 拡張されたスカラー値を表すテキストのJSONオブジェクト
ネイティブ・バイナリJSONデータ(OSON形式)は、SQL型に対応していてJSON標準には含まれてないスカラー型(dateなど)の追加によってJSON言語を拡張します。Oracle Databaseでは、このような非標準値を含め、JSONスカラー値を表すテキストのJSONオブジェクトの使用もサポートしています。 - JSONデータ型の値の比較とソート
SQLデータ型JSON
の値に対する正規のソート順について説明します。すべてのJSON値を比較するために使用されます。 - SQL値とJSONデータ型値の比較
JSON
型値をJSON
以外の型のSQL値と比較するとき、同じファミリの2つのJSON
型値(数値など)を比較するときと同じルールが適用されます。ただし、SQL型がそのファミリのJSON言語型のいずれかに対応しているという前提です。
関連トピック
関連項目:
-
JSON
データ型の詳細は、『Oracle Database SQL言語リファレンス』 -
コンストラクタ
JSON
の詳細は、Oracle Database SQL言語リファレンス -
SQL/JSONファンクション
json_scalar
の詳細は、『Oracle Database SQL言語リファレンス』を参照してください -
SQL/JSONファンクション
json_serialize
の詳細は、『Oracle Database SQL言語リファレンス』を参照してください
親トピック: Oracle DatabaseのJSON
2.2.1 JSONデータ型コンストラクタ
JSON
データ型コンストラクタのJSON
は、テキストのJSON値(スカラー、オブジェクトまたは配列)を入力としてを受け取って解析し、その値をJSON
型のインスタンスとして返します。また、SQL型VECTOR
、ユーザー定義のPL/SQL型またはSQL集計型のインスタンスを入力にすることもできます。
ノート:
コンストラクタJSON
は、データベース初期化パラメータcompatible
が少なくとも20
の場合にのみ使用できます。それ以外の場合、渡される入力にかかわらず、コンストラクタでエラーが発生します。
たとえば、入力がSQL文字列'{}'
の場合、返されるJSON
型インスタンスは空のオブジェクト{}
です。入力が'{a : {"b":"beta", c:[+042, "gamma",]},}'
の場合は、JSON
インスタンス{"a":{"b":"beta","c":[42,"gamma"]}}
が返されます。
(テキストの入力を解析せず、JSONの文字列値に変換するだけのSQL/JSONファンクションjson_scalar
の動作とは対照的です。json_scalar('{}')
は、JSON文字列"{}"
を返します。コンストラクタJSON
を使用して同じJSON文字列を生成するには、明示的な二重引用符文字を追加する必要があります(JSON('"{}"')
)。)
コンストラクタJSON
へのテキストの入力は、リテラルのSQL文字列か、VARCHAR2
型、CLOB
型またはBLOB
型のいずれかのデータになります。入力がSQLのNULL
値の場合は、SQLのNULL
のJSON
型インスタンスが生成されます。
コンストラクタへの非テキストの入力は、VECTOR
型または次のユーザー定義データ型のいずれかのインスタンスになります:
-
PL/SQL VARRAY
-
PL/SQLレコード
-
SQLオブジェクト型
-
binary_integer
コレクションによるPL/SQL索引(IBBI) -
PL/SQLネスト表
-
PL/SQL連想配列
引数としてのVECTOR
インスタンスは、結果的にvector型のOracle JSONスカラー値になります。
引数としてのVARRAYインスタンスは、結果的にJSON配列になります。JSON配列の要素は、VARRAYコレクションの要素から(順番に)作成されます。
その他の各インスタンスは、結果的にJSONオブジェクトになります。JSONオブジェクトのメンバーは、レコード・インスタンスまたはSQLオブジェクト・インスタンスの属性、IBBIまたはネスト表インスタンスの索引、および連想配列インスタンスのキーと値のペアから作成されます。
コンストラクタによって返される値は、Oracleでサポートされている任意のJSON値です。これには、標準JSON言語型の値(オブジェクト、配列、文字列、ブール、null
および数値)が含まれます。また、非標準のOracleスカラーJSON値、つまり、Oracle固有のスカラー型(binary、date、day-second interval、double、float、timestamp、timestamp with time zone、vectorおよびyear-month interval)の値も含まれます。コンストラクタをキーワードEXTENDED
とともに使用すると、Oracle固有の型の値は、テキストのJSON入力のOracle拡張オブジェクト・パターンから導出できます。
テキスト入力が整形式のJSONデータでない場合は、エラーが発生します。これには、重複するフィールド(キー)名がある1つ以上のオブジェクトがそれに含まれている場合などがあります。ただし、緩和されたJSON構文をそれに使用することはできます。このような構文緩和を除き、整形式にするには、入力データがRFC 8259に準拠している必要があります。
テキスト入力で厳密なJSON構文のみが使用されるようにする必要がある場合は、SQL条件is json
を使用してそれをフィルタ処理します。このコードにより、厳密でない構文が受け入れられなくなります:
SELECT JSON(jcol) FROM table WHERE jcol is json (STRICT);
利便性のために、テキストのJSONデータを使用して、JSON
型の列に対してINSERT
またはUPDATE
操作を実行する場合、テキストのデータはコンストラクタJSON
で暗黙的にラップされます。
コンストラクタJSON
のユースケースとしては、テキストのJSONデータをJSON
型に即時に解析および変換する場合があります。(かわりに、WHERE
句で条件is json
を使用することもできます。)たとえば、外部表の文字列値またはデータをバインド変数としてコンストラクタに渡すことができます。
たとえば、コンストラクタJSON
を使用すると、is json
チェック制約を使用してデータベースに格納されていないテキスト・データを整形式にすることができます。その後、結果のJSON
型のデータに対して単純なドット表記法の問合せ構文を使用できます。(整形式であることが認識されていないデータには、ドット表記法を使用できません。)例2-1に、これを示します。
例2-1 JSON型へのテキストのJSONデータの即時の変換
この例では、単純なドット表記法構文を使用して、データベースが整形式であることが認識されていないテキストJSONデータからフィールドを選択します。選択する前に、データをJSON
型のデータに変換します。コンストラクタJSON
は、引数が整形式ではない場合、エラーを発生させます。(ドット表記法構文では、表の別名を使用する必要があり、この場合はj
です。)
WITH jtab AS
(SELECT JSON(
'{ "name" : "Alexis Bull",
"Address": { "street" : "200 Sporting Green",
"city" : "South San Francisco",
"state" : "CA",
"zipCode" : 99236,
"country" : "United States of America" } }')
AS jcol FROM DUAL)
SELECT j.jcol.Address.city FROM jtab j;
関連トピック
関連項目:
-
コンストラクタ
JSON
の詳細は、『Oracle Database SQL言語リファレンス』のJSON型コンストラクタに関する項を参照してください。 -
非テキスト引数の
JSON
型の値への変換の詳細は、『Oracle Database PL/SQL言語リファレンス』のPL/SQL型とJSON型の変換に関する項を参照してください。
親トピック: JSONデータ型
2.2.2 SQL/JSONファンクションJSON_SCALAR
SQL/JSONファンクションjson_scalar
は、SQLスカラー値を入力として受け取り、対応するJSONスカラー値をJSON
型インスタンスとして返します。値には、JSON標準に含まれない日付など、Oracle固有のJSON言語型を使用できます。
ファンクションjson_scalar
は、データベース初期化パラメータcompatible
が少なくとも20
の場合にのみ使用できます。それ以外の場合、エラーが発生します。
json_scalar
は、スカラー生成関数と考えることができます。JSONデータをサポートする任意のSQLデータ型を返すことができるSQL/JSON生成関数とは異なり、json_scalar
は常にJSON
型インスタンスを返します。
json_scalar
の引数には、BINARY_DOUBLE
、BINARY_FLOAT
、BLOB
、BOOLEAN
、CHAR
、CLOB
、DATE
、INTERVAL DAY TO SECOND
、INTERVAL YEAR TO MONTH
、JSON
、NCHAR
、NCLOB
、NUMBER
、NVARCHAR2
、RAW
、TIMESTAMP
、TIMESTAMP WITH TIME ZONE
、VARCHAR
、VARCHAR2
またはVECTOR
のいずれかのSQLデータ型のインスタンスを使用できます。
返されるJSON
型インスタンスは、OracleでサポートされるJSON言語スカラー値です。たとえば、json_scalar(current_timestamp)
は、timestamp
型のOracle JSON値を返します(SQLデータ型JSON
のインスタンスとして)。
入力がJSON
型の場合、json_scalar
は次のように動作します。
-
JSONスカラー値に対応する入力が返されます。
-
JSON非スカラー値に対応する入力はエラーになります。エラー・ハンドラがデフォルトで
NULL ON ERROR
の場合は、SQLNULL
(JSON
データ型)が返されます。
ヒント:
json_scalar
は、デフォルトでは非スカラー入力に対してNULL
を返し、非スカラーJSON値が関与する比較はスカラーとスカラーの比較よりもコストがかかることがあるため、JSONデータの順序付けや比較の際には、json_scalar
でラップした後に簡単な手動最適化を実施することで、比較対象のデータから非スカラーを効率的にプルーニングできます。(より正確には、すぐに比較されるNULL
に置換します)。
たとえば、次のようなコードがあるとします。
SELECT data FROM customers c
ORDER BY c.data.revenue;
次を使用します:
SELECT data FROM customers c
ORDER BY json_scalar(c.data.revenue);
ノート:
JSONパス式項目メソッドtype()
を使用して、JSONスカラー値のJSON言語型を決定できます。
"binary"
、"boolean"
、"date"
、"daysecondInterval"
、"double"
、"float"
、"number"
、"null"
、"string"
、"timestamp"
、"timestamp with time zone"
、"vector"
、 "yearmonthInterval"
のいずれかのJSON文字列として、型名が返されます。たとえば、対象となるスカラーJSON値がtimestamp with time zone型の場合、type()
は文字列"timestamp with time zone"
を返します。参照:
表2-2 JSON_SCALARによる型変換: SQL型からOracle JSON型へ
SQL型(ソース) | JSON言語型(変換先) |
---|---|
VARCHAR2 、VARCHAR 、NVARCHAR2 、CHAR またはNCHAR |
string |
CLOB またはNCLOB |
string |
BLOB |
binary |
RAW |
binary |
BOOLEAN |
boolean |
NUMBER |
number (無限値または未定義値の場合はstring) |
BINARY_DOUBLE |
double (無限値または未定義値の場合はstring) |
BINARY_FLOAT |
float (無限値または未定義値の場合はstring) |
DATE |
date |
TIMESTAMP |
timestamp |
TIMESTAMP WITH TIME ZONE |
タイム・ゾーン付きタイムスタンプ |
INTERVAL DAY TO SECOND |
daysecondInterval |
INTERVAL YEAR TO MONTH |
yearmonthInterval |
例外は、正の無限大と負の無限大の数値、および数値演算の結果が未定義の値(非数値、つまりNaN
)です。これらはJSON数値として表現できません。それらの値の場合、json_scalar
は数値型ではなく、JSON文字列"Inf"
、"-Inf"
および"Nan"
をそれぞれ返します。
json_scalar
によって返されるJSON
型の値は、導出元のSQLデータ型を記憶しています。その後、json_value
(またはjson_value
のセマンティクスを持つjson_table
列)を使用してそのJSON
型の値を抽出し、対応する型変換項目メソッドを使用した場合、抽出された値は元のSQLデータ型になります。たとえば、次の問合せではSQLのTIMESTAMP
値が返されます。
SELECT json_value(json_scalar(current_timestamp), '$.timestamp()')
FROM DUAL;
なお、引数がSQLの文字列値である場合(VARCHAR2
、VARCHAR
、NVARCHAR
、CHAR
、NCHAR
またはCLOB
)、json_scalar
では、それがJSON文字列値に変換されるだけです。入力はJSONデータとして解析されません。
たとえば、json_scalar('{}')
は、JSON文字列値"{}"
を返します。コンストラクタJSON
はSQL文字列を解析するため、同じ入力に対して空のJSONオブジェクト{}
を返します。コンストラクタJSON
を使用して同じJSON文字列を生成するには、入力に二重引用符文字を明示的に記述する必要があります(JSON('"{}"')
)。
json_scalar
の引数がSQL NULL
値である場合、次のように戻り値を取得できます:
-
SQL
NULL
(デフォルトの動作) -
JSON
null
(キーワードJSON NULL ON NULL
を使用、キーワードJSON
はオプション) -
空のJSON文字列
""
(キーワードEMPTY STRING ON NULL
を使用)
SQL NULL
を返すデフォルトの動作は、JSONスカラー値が返されるルールの唯一の例外です。
ノート:
ファンクションjson_scalar
はタイムスタンプ値を保持しますが、タイムスタンプからタイムゾーン情報を削除します。タイムゾーン情報は、UTC時間に変換することによって考慮されます。表2-4を参照してください。
明示的なタイムゾーン情報をJSONデータとして追加する必要がある場合は、SQLのTIMESTAMP WITH TIME ZONE
インスタンスとは別にそれを記録して、JSON生成関数に渡します。例2-2に、これを示します。
例2-2 JSONデータへのタイムゾーン情報の追加
この例では、表にTIMESTAMP WITH TIME ZONE
値を挿入してから、生成関数json_object
を使用してJSONオブジェクトを作成します。SQLファンクションjson_scalar
およびextract
を使用して、json_object
のJSONタイムスタンプおよび数値のタイムゾーンの入力を提供します。
CREATE TABLE t (tz TIMESTAMP WITH TIME ZONE);
INSERT INTO t
VALUES (to_timestamp_tz('2019-05-03 20:00:00 -8:30',
'YYYY-MM-DD HH24:MI:SS TZH:TZM'));
-- This query returns the UTC timestamp value "2019-05-04T04:30:00"
SELECT json_scalar(tz) FROM t;
-- Create a JSON object that has 3 fields:
-- timestamp: JSON timestamp value (UTC time):
-- timeZoneHours: hours component of the time zone, as a JSON number
-- timeZoneMinutes: minutes component of the time zone, as a JSON number
SELECT json_object('timestamp' : json_scalar(tz),
'timezoneHours' : extract(TIMEZONE_HOUR FROM tz),
'timezoneMinutes' : extract(TIMEZONE_MINUTE FROM tz))
FROM t;
-- That query returns a JSON object and prints it in serialized form.
-- The JSON timestamp value is serialized as an ISO 8601 date-time string.
-- The time-zone values (JSON numbers) are serialized as numbers.
--
-- {"timestamp" : "2019-05-04T04:30:00",
-- "timezoneHours" : -8,
-- "timezoneMinutes" : -30}
関連トピック
関連項目:
-
SQL/JSONファンクション
json_scalar
の詳細は、『Oracle Database SQL言語リファレンス』の「JSON_SCALAR」を参照してください -
『Oracle Database SQL言語リファレンス』の「JSONデータ型」
-
SQLデータ型
CHAR
、NCHAR
、VARCHAR2
、VARCHAR
およびNVARCHAR2
の詳細は、『Oracle Database SQL言語リファレンス』の「文字データ型」を参照してください -
SQLデータ型
BLOB
、CLOB
およびNCLOB
の詳細は、『Oracle Database SQL言語リファレンス』の「ラージ・オブジェクト(LOB)データ型」を参照してください -
SQLデータ型
NUMBER
、BINARY_DOUBLE
およびBINARY_FLOAT
の詳細は、『Oracle Database SQL言語リファレンス』の「数値データ型」を参照してください -
SQLデータ型
DATE
、TIMESTAMP
、TIMESTAMP WITH TIME ZONE
、INTERVAL YEAR TO MONTH
およびINTERVAL DAY TO SECOND
の詳細は、『Oracle Database SQL言語リファレンス』の「日時データ型と期間データ型」を参照してください -
『Oracle Database SQL言語リファレンス』の「ブール・データ型」
-
SQLデータ型
RAW
の詳細は、『Oracle Database SQL言語リファレンス』の「RAWデータ型とLONG RAWデータ型」を参照してください
親トピック: JSONデータ型
2.2.3 SQL/JSONファンクションJSON_SERIALIZE
SQL/JSONファンクションjson_serialize
は、入力としてJSONデータ(SQLデータ型BLOB
、CLOB
、JSON
、VARCHAR2
)を受け取り、そのテキスト表現を(BLOB
またはVARCHAR2
データとして)返します。VARCHAR2(4000)
はデフォルトの戻り型です。
通常、問合せの結果を変換するには、json_serialize
を使用します。ファンクションでは、エラー句およびRETURNING句がサポートされています。必要に応じて、次の任意の組合せを実行できます:脚注1
-
標準のASCII Unicodeエスケープ・シーケンスを使用して、すべての非ASCII Unicode文字を自動的にエスケープします(キーワード
ASCII
)。 -
結果をフォーマット出力します(キーワード
PRETTY
)。 -
結果に含まれるオブジェクトのメンバーを、フィールド名でアルファベットの昇順に並べ替えます(キーワード
ORDERED
)。この順序は、AL32UTF8文字セットで表されるバイナリ順序の
VARCHAR2
照合で定義されます。つまり、文字はUnicodeのコード・ポイントに従って順序付けされます。 -
戻り型に適合させるように結果を切り捨てます(キーワード
TRUNCATE
)。 -
Oracle固有のスカラーJSON言語型の値をOracle拡張オブジェクト・パターンに変換します(キーワード
EXTENDED
) — 「拡張されたスカラー値を表すテキストのJSONオブジェクト」を参照してください。
デフォルトでは、ファンクションjson_serialize
は常にJSON標準(RFC 8259)に準拠したJSONデータを生成します。その場合、返されるデータで使用されるのは、JSON言語の標準のデータ型(オブジェクト、配列、スカラー型の文字列、数値、ブールおよびNull)のみです。
シリアライズされて格納されたJSONデータには、OracleでJSON言語に追加されたスカラー型の値が含まれることもあります。このような型のJSONデータは、シリアライズされるときに表2-3のように変換されます。たとえば、JSON言語型doubleの数値は、JSONのnumberのテキスト表現に変換することによってシリアライズされます。
ノート:
入力されたJSON string値はそのまま(変更なし)で返されます。ここで指定されている形式とは異なる形式を使用して非文字列スカラーJSON値をシリアライズする場合は、最初にto_char
などのSQL変換関数を使用して、必要に応じて書式設定された文字列値を生成し、その値をjson_serialize
に渡します。
表2-3 JSON_SERIALIZEによるOracle JSON言語型から標準JSON言語型への変換
Oracle JSONスカラー型(type()によるレポート) | 標準のJSON型 | ノート |
---|---|---|
binary | string |
変換は、SQLファンクション |
date | string |
文字列はISO 8601の日付形式です(YYYY-MM-DD)。たとえば、 |
daysecondInterval | string |
文字列は、SQLファンクション PdDThHmMsS。ここで、d、h、mおよびsは、それぞれ日、時間、分および秒の数字です。たとえば、 sには、整数部の数字とそれに続く小数点および小数部の数字を指定することもできます。たとえば、 値がゼロの数字は、その指定子とともに省略されます。たとえば、 |
double | number |
変換は、SQLファンクション |
float | number |
変換は、SQLファンクション |
timestamp | string |
文字列はISO 8601の日時形式YYYY-MM-DDThh:mm:ss.ssssssです。たとえば、 |
タイム・ゾーン付きタイムスタンプ | string | 文字列はISO 8601の日時形式YYYY-MM-DDThh:mm:ss.ssssss(+|-)hh:mmであるか、UTCからのゼロのオフセットの場合はYYYY-MM-DDThh:mm:ss.ssssssZです。たとえば、"2019-05-21T10:04:02.123000-08:00" または"2019-05-21T10:04:02.123000Z" などです。
|
ベクター脚注2 | array | JSON配列の要素はJSON数値です。これらはvectorのSQL数値から変換されます。 |
yearmonthInterval | string |
文字列は、SQLファンクション PyYmM。ここで、yは年の数字、およびmは月の数字です。たとえば、 年または月がゼロの場合は、それと指定子が省略されます。たとえば、 |
脚注2 JSONベクター値はスカラー値ですが、ベクター・コンポーネントを表示するためにJSON配列としてシリアライズされます。
json_serialize
を使用すると、バイナリのJSONデータをテキスト形式(CLOB
またはVARCHAR2
)に変換することや、フォーマット出力やASCII Unicode以外の文字のエスケープによってテキストのJSONデータを変換することができます。重要なユースケースとして、BLOB
またはJSON
型の列に格納されているJSONデータをシリアライズする場合があげられます。
(JSON
データ型は、データベース初期化パラメータcompatible
が少なくとも20の場合にのみ使用できます。)
BLOB
の結果はAL32UTF8文字セットです。ただし、json_serialize
によって返されるデータ型に関係なく、返されるデータはテキストのJSONデータを表します。
ノート:
JSONパス式項目メソッドtype()
を使用して、JSONスカラー値のJSON言語型を決定できます。
"binary"
、"boolean"
、"date"
、"daysecondInterval"
、"double"
、"float"
、"number"
、"null"
、"string"
、"timestamp"
、"timestamp with time zone"
、"vector"
、 "yearmonthInterval"
のいずれかのJSON文字列として、型名が返されます。たとえば、対象となるスカラーJSON値がtimestamp with time zone型の場合、type()
は文字列"timestamp with time zone"
を返します。参照:
ノート:
SQLファンクションvector_serialize
を使用して、SQL VECTOR
インスタンスを数値のテキストJSON配列にシリアライズできます。(ファンクションjson_serialize
は、JSONデータのみをシリアライズします。『Oracle Database SQL言語リファレンス』のvector_serializeを参照してください。)
関連項目:
-
SQL/JSONファンクション
json_serialize
の詳細は、『Oracle Database SQL言語リファレンス』の「JSON_SERIALIZE」を参照してください -
SQLファンクション
rawtohex
の詳細は、『Oracle Database SQL言語リファレンス』のRAWTOHEXに関する項を参照してください - SQLファンクション
to_number
の詳細は、『Oracle Database SQL言語リファレンス』のTO_NUMBERに関する項を参照してください
例2-3 JSON_SERIALIZEを使用したJSON型またはBLOBデータのオブジェクト・メンバーが順序付けされたフォーマット出力テキストへの変換
この例では、表j_purchaseorder
の列data
から選択された、フィールドPONumber
のデータの値が1600
であるJSON発注書を、シリアライズし、オブジェクト・メンバーを順序付けし、整形して出力します。戻り値のデータ型は、VARCHAR2(4000)
(デフォルトの戻り型)です。
例4-1では、JSON
型の列を持つ表の作成方法を示しています。json_serialize
を使用してBLOB
データをシリアライズすることもできます。
SELECT json_serialize(data PRETTY ORDERED)
FROM j_purchaseorder po
WHERE po.data.PONumber = 1600;
例2-4 JSON_SERIALIZEを使用した非ASCII Unicode文字のASCIIエスケープ・コードへの変換
この例では、非ASCII文字(€)を含む文字列フィールド値があるオブジェクトをシリアライズします。また、フィールドをアルファベット順に順序付けします。
SELECT json_serialize('{"price" : 20, "currency" : "€"}' ASCII ORDERED)
FROM DUAL;
問合せは、{"currency" : "\u20AC", "price" : 20}
を返します。
2.2.4 JSONコンストラクタ、JSON_SCALARおよびJSON_SERIALIZE: サマリー
JSON
データ型コンストラクタJSON
、SQL/JSONファンクションjson_scalar
およびSQL/JSONファンクションjson_serialize
間の関係について概要を示します。
コンストラクタJSON
とファンクションjson_scalar
はどちらもJSON
以外のSQL型インスタンスを受け取り、JSON
データ型のインスタンスを返します。
コンストラクタは、(1)テキストJSONデータ(VARCHAR2
、CLOB
またはBLOB
のインスタンス)のみを入力として受け取るか、(2) VECTOR
型インスタンスを受け取ります。他の入力データ型の場合はエラーが発生します。
ファンクションjson_scalar
は、複数のスカラーSQL型のインスタンスを入力として受け取ります。VARCHAR2
またはCLOB
の入力の場合は、常にJSON言語の文字列をJSON
型インスタンスとして返します。
コンストラクタによって返される値は、Oracle固有のスカラー型(binary、date、day-second interval、double、float、timestamp、timestamp with time zone、vectorおよびyear-month interval)の値を含め、Oracleでサポートされている任意のJSON値です。コンストラクタをキーワードEXTENDED
とともに使用すると、値は、テキストのJSON入力のOracle拡張オブジェクト・パターンから導出できます。
json_scalar
によって返されるJSON値は常にスカラーです(コンストラクタの場合と同じJSON言語型(スカラー型以外(オブジェクトおよび配列)の場合を除く))。たとえば、入力がSQL型DOUBLE
のインスタンスの場合は、(Oracle固有の) JSON言語型doubleの値を表すJSON
型インスタンスになります。
SQL/JSONファンクションjson_serialize
をJSON
型インスタンスに適用すると、非標準OracleスカラーJSON値が標準JSONスカラー値として返されます。ただし、json_serialize
をキーワードEXTENDED
とともに使用すると、Oracle固有のスカラーJSON言語型の値は、テキストのJSON出力のOracle拡張オブジェクト・パターンにシリアライズできます。(json_serialize
をVECTOR
型インスタンスに適用することもできます。この場合、数値のテキストJSON配列が返されます。)
表2-4では、JSONデータとしての様々なSQL値に対してコンストラクタJSON
およびSQLファンクションjson_scalar
を使用してJSON
型インスタンスを生成した場合の結果をまとめ、それらのインスタンスをシリアライズした場合の結果を示します。
コンストラクタは、入力を解析します。この入力はテキストのJSONデータであることが必要です(そうでない場合は、エラーが発生します)。ファンクションjson_scalar
は、入力のSQLスカラー値をJSON言語のスカラー値に変換します。VARCHAR2
またはCLOB
をjson_scalar
に入力すると、常にJSON文字列値が生成されます(入力はJSONデータとして解析されません)。
次の事実を除き、コンストラクタによって生成された値をシリアライズした結果は、コンストラクタが受け取ったの値と同じテキスト表現です(ただし、テキストのSQLデータ型はVARCHAR2
、CLOB
およびBLOB
の間で同じであるとは限りません)。
-
コンストラクタは緩慢なJSON構文を受け入れますが、
json_serialize
は常に厳密な構文を返します。 -
入力のJSONオブジェクトに重複したフィールド名がある場合、1つのフィールド値のペア以外のすべてがコンストラクタによって削除されます。
-
通常、オブジェクト内のフィールド値のペアの順序は維持されません。出力順序が入力順序と異なる場合があります。
-
コンストラクタが適用されるテキストのデータに拡張JSON構造体(非標準スカラーJSON値を指定するJSONオブジェクト)が含まれる場合、結果の
JSON
型データには(キーワードEXTENDED
の使用により)これらの構造体をSQLスカラー値に変換した結果のスカラー値がいくつか含まれることがあります。json_serialize
(キーワードEXTENDED
を指定)を結果のJSON
型データに適用すると、その結果には、逆方向に変換した結果の拡張JSON構造体がいくつか含まれることがあります。ただし、この2方向の変換は、一般的に逆方向の操作ではありません。これらはOracle構造体では真逆になりますが、Oracle以外の拡張JSON構造体では真逆になりません。拡張JSON構造体は
JSON
型のOracle固有のJSONスカラー値に変換されるため、拡張JSONオブジェクトとしてテキストのJSONデータにシリアライズされ直すと、元々Oracle以外の形式である場合、失われる可能性があります。
表2-4 コンストラクタJSONおよびSQL/JSONファンクションJSON_SCALARの影響: 例
入力SQL値 | SQL型 | JSONコンストラクタからのJSON値 | JSON_SCALARからのJSONスカラー値 |
---|---|---|---|
{a:1} |
VARCHAR2 |
|
|
[1,2,3] |
VARCHAR2 |
|
|
TRUE (大/小文字は区別されません)
|
BOOLEAN |
|
|
true |
VARCHAR2 |
|
|
null |
VARCHAR2 |
|
|
NULL 脚注3
|
VARCHAR2 |
|
|
"city" |
VARCHAR2 |
|
|
city |
VARCHAR2 |
エラー — 入力は有効なJSONデータではありません(JSONスカラー値 |
|
{"$numberDouble" : "1E300"} または{"$numberDouble" : 1E300} (拡張JSONオブジェクト。) |
VARCHAR2 |
double型のJSONスカラー |
入力の |
{"$numberDecimal" : "1E300"} または{"$numberDecimal" : 1E300} (拡張JSONオブジェクト。) |
VARCHAR2 |
number型のJSONスカラー。 |
入力の |
{"$oid" : "deadbeefcafe0123456789ab"} または{"$rawid" : "deadbeefcafe0123456789ab"} (拡張JSONオブジェクト。) |
VARCHAR2 |
binary型のJSONスカラー。 |
入力の |
{"$date" : "2020-11-24T12:34:56"} または{"$oracleDate" : "2020-11-24T12:34:56"} (拡張JSONオブジェクト。) |
VARCHAR2 |
date型のJSONスカラー。 |
入力の |
3.14 |
VARCHAR2 |
|
|
3.14 |
NUMBER |
エラー — テキストのJSONデータではありません( |
|
3.14 |
BINARY_DOUBLE |
エラー — テキストのJSONデータではありません( |
|
3.14
|
NUMBER 。$numberDecimal 拡張オブジェクトから導出されたものとして内部的にタグ付けされます
|
number型のJSONスカラー。 |
元の拡張オブジェクトと同じ内容を持つJSON文字列 |
RAW 値
|
RAW 。$rawid または$oid 拡張オブジェクトから導出されたものとして内部的にタグ付けされます
|
binary型のJSONスカラー。 |
元の拡張オブジェクトと同じ内容を持つJSON文字列 |
to_date('20.07.1974') を評価することによって生成されるSQL日付値 |
DATE |
エラー — テキストのJSONデータではありません |
|
to_timestamp('2019-05-23 11:31:04.123', 'YYYY-MM-DD HH24:MI:SS.FF') を評価することによって生成されるSQLのタイムスタンプ値 |
TIMESTAMP |
エラー — テキストのJSONデータではありません |
|
to_timestamp_tz('2019-05-23 11:31:04.123 -8', 'YYYY-MM-DD HH24:MI:SS.FF TZH') を評価することによって生成されるSQLのタイムスタンプ値 |
TIMESTAMP WITH TIME ZONE |
エラー — テキストのJSONデータではありません |
|
VECTOR インスタンス
|
VECTOR |
vector型のJSONスカラー | vector型のJSONスカラー |
脚注3 これはVARCHAR2
型のSQL NULL
値であり、文字NULL
を含むSQL文字列ではありません。
関連トピック
関連項目:
-
『Oracle Database SQL言語リファレンス』JSON型コンストラクタに関する項
-
『Oracle Database SQL言語リファレンス』の「JSON_SCALAR」
-
『Oracle Database SQL言語リファレンス』の「JSON_SERIALIZE」
親トピック: JSONデータ型
2.2.5 拡張されたスカラー値を表すテキストのJSONオブジェクト
ネイティブ・バイナリJSONデータ(OSON形式)は、SQL型に対応していてJSON標準には含まれてないスカラー型(dateなど)を追加することでJSON言語を拡張します。Oracle Databaseでは、このような非標準値を含め、JSONスカラー値を表すテキストのJSONオブジェクトの使用もサポートしています。
このような拡張オブジェクトが含まれるテキストのJSONデータからネイティブ・バイナリJSONデータを作成する場合、必要に応じて、対応する(ネイティブ・バイナリ)JSONスカラー値に置き換えることができます。
拡張オブジェクトの例は、{"$numberDecimal":31}
です。これは、非標準型10進数のJSONスカラー値を表し、そのように解釈されると、ネイティブ・バイナリ形式の10進数に置き換えられます。
たとえば、JSONデータ型コンストラクタJSON
を使用する場合、キーワードEXTENDED
を使用すると、テキストの入力で認識された拡張オブジェクトがネイティブ・バイナリJSONの結果では対応するスカラー値に置き換えられます。キーワードEXTENDED
を含めなければ、このような置換は発生しません。テキストの拡張JSONオブジェクトは、ネイティブ・バイナリ形式のJSONオブジェクトにそのまま変換されるだけです。
逆方向では、SQL/JSONファンクションjson_serialize
を使用してバイナリJSONデータをテキストのJSONデータ(VARCHAR2
、CLOB
またはBLOB
)としてシリアライズする場合、キーワードEXTENDED
を使用して、(ネイティブ・バイナリ)JSONスカラー値を対応するテキストの拡張JSONオブジェクトに置き換えることができます。
ノート:
使用するデータベースがOracle Autonomous Databaseの場合、PL/SQLプロシージャDBMS_CLOUD.copy_collection
を使用して、Oracle NoSQL Databaseなどの一般的なNoSQLデータベースによって生成されるようなJSONデータのファイルからJSONドキュメント・コレクションを作成できます。
ejson
をプロシージャのtype
パラメータの値として使用すると、入力ファイルで認識された拡張JSONオブジェクトが、結果のネイティブ・バイナリJSONコレクションでは対応するスカラー値に置き換えられます。もう1つの方向では、ファンクションjson_serialize
をキーワードEXTENDED
とともに使用して、結果のテキストのJSONデータで、スカラー値を拡張JSONオブジェクトに置き換えることができます。
拡張オブジェクトの主なユースケースを2つ、次に示します。
-
交換(インポート/エクスポート):
-
拡張オブジェクトが含まれる既存のJSONデータを(どこかから)取り込みます。
-
データベースの外部でなんらかに使用するため、ネイティブ・バイナリJSONデータを拡張オブジェクトが含まれるテキストのJSONデータとしてシリアライズします。
-
-
ネイティブ・バイナリJSONデータの検査: 対応する拡張オブジェクトを調べて、保持しているものを確認します。
交換目的の場合、拡張オブジェクトをネイティブ・バイナリJSONスカラーに変換して、Oracle NoSQL Databaseなどの一般的なNoSQLデータベースによって生成されたファイルからJSONデータを取り込むことができます。もう1つの方向では、Oracle固有のスカラーJSON値を対応するテキストの拡張JSONオブジェクトに置き換えて、ネイティブ・バイナリJSONデータをテキストのデータとしてエクスポートすることができます。
ヒント:
検査の例として、{"dob" : "2000-01-02T00:00:00"}
などのオブジェクトを、ネイティブJSONデータをシリアライズした結果として考えてみます。"2000-01-02T00:00:00"
は、日付型のネイティブ・バイナリ値をシリアライズした結果ですか。それとも、ネイティブ・バイナリ値は単なる文字列ですか。json_serialize
をキーワードEXTENDED
とともに使用すると、わかります。
拡張オブジェクト・フィールドからスカラーJSON型へのマッピングは、通常、多対1です。複数種類の拡張JSONオブジェクトを特定のスカラー値にマップできます。たとえば、拡張JSONオブジェクトの{"$numberDecimal":"31"}
と{"$numberLong:"31"}
は、どちらも値31のJSON言語スカラー型numberとして変換され、これらの各JSONスカラーに対して項目メソッドtype()
は"number"
を返します。
項目メソッドtype()
は、対象値のJSON言語スカラー型を(JSON文字列として)報告します。スカラー値の中には、同じスカラー型であっても内部的に区別できるものがあります。これにより、通常、ファンクションjson_serialize
(キーワードEXTENDED
を指定)による元の拡張JSONオブジェクトの再構築が可能になります。そのようなスカラー値は、その値を実装する各種のSQL型を使用するか、導出元の拡張JSONオブジェクトの種類でタグ付けすることで、内部的に区別されます。
json_serialize
で元の拡張JSONオブジェクトを再構築すると、結果は元のものと必ずしもテキスト的に同一であるとはかぎりませんが、常に意味的に等しいです。たとえば、{"$numberDecimal":"31"}
と{"$numberDecimal":31}
は、フィールド値の型が異なっていても(文字と数値)、意味的に等しくなります。これらは同じ内部値に変換され、それぞれが$numberDecimal
拡張オブジェクトから導出されたものとしてタグ付けされます(同一タグ)。ただし、シリアライズすると、どちらの結果も{"$numberDecimal":31}
になります。Oracleでは常に、最も直接関連する型がフィールド値に使用されます。この場合は、スカラー型numberのJSON言語値31
です。
表2-5に、使用される各種の型の間の対応関係を示します。(1)入力として使用される拡張オブジェクトの型、(2)項目メソッドtype()
によって報告される型、(3)内部で使用されるSQL型、(4)ファンクションjson_serialize
による出力として使用される標準のJSON言語型、および(5)キーワードEXTENDED
が指定されている場合のjson_serialize
による拡張オブジェクト出力の型の間でマップします。
表2-5 拡張JSONオブジェクト型の関係
拡張オブジェクト型(入力) | Oracle JSONスカラー型(type()によるレポート) | SQLスカラー型 | 標準のJSONスカラー型(出力) | 拡張オブジェクト型(出力) |
---|---|---|---|---|
JSON数値の値、数値を表す文字列、または"Infinity" 、"-Infinity" 、"Inf" 、"-Inf" 、"Nan" 脚注4のいずれかの文字列による$numberDouble
|
double | BINARY_DOUBLE |
number |
JSON数値の値、または"Inf" 、"-Inf" 、"Nan" 脚注5のいずれかの文字列による$numberDouble |
$numberDouble の場合と同じ値の$numberFloat |
float | BINARY_FLOAT |
number |
$numberDouble の場合と同じ値の$numberFloat |
$numberDouble の場合と同じ値の$numberDecimal |
number | NUMBER |
number |
$numberDouble の場合と同じ値の$numberDecimal |
値が符号付き32ビット整数または数値を表す文字列の$numberInt
|
number | NUMBER |
number |
$numberDouble の場合と同じ値の$numberInt |
値がJSON数値または数値を表す文字列の$numberLong
|
number | NUMBER |
number |
$numberDouble の場合と同じ値の$numberLong |
値が次のいずれかの
値がbase64文字の文字列の場合、拡張オブジェクトには、値が0または4のフィールド |
binary | BLOB またはRAW |
string 変換は、SQLファンクション |
次のいずれか1つを使用します。
|
値が24文字の16進文字列の$oid
|
binary | RAW(12) |
string 変換は、SQLファンクション |
値が24文字の16進文字列の$rawid
|
値が偶数文字の16進文字列の$rawhex
|
binary | RAW |
string 変換は、SQLファンクション |
値がbase64文字の文字列で、右側に= 文字が埋め込まれている$binary
|
値が24または32文字の16進文字列の$rawid
|
binary | RAW |
string 変換は、SQLファンクション |
$rawid |
値がISO 8601の日付文字列の$oracleDate
|
date | DATE |
string |
値がISO 8601の日付文字列の$oracleDate
|
値がISO 8601のタイムスタンプ文字列の$oracleTimestamp
|
timestamp | TIMESTAMP |
string |
値がISO 8601のタイムスタンプ文字列の$oracleTimestamp
|
数値のタイムゾーン・オフセットまたはZ が指定されたISO 8601のタイムスタンプ文字列が値の$oracleTimestampTZ |
タイム・ゾーン付きタイムスタンプ | TIMESTAMP WITH TIME ZONE |
string |
数値のタイムゾーン・オフセットまたはZ が指定されたISO 8601のタイムスタンプ文字列が値の$oracleTimestampTZ |
値が次のいずれかの
|
タイム・ゾーン付きタイムスタンプ | TIMESTAMP WITH TIME ZONE |
string |
数値のタイムゾーン・オフセットまたはZ が指定されたISO 8601のタイムスタンプ文字列が値の$oracleTimestampTZ |
SQLファンクションto_dsinterval に指定されたISO 8601の時間隔文字列が値の$intervalDaySecond |
daysecondInterval | INTERVAL DAY TO SECOND |
string |
SQLファンクションto_dsinterval に指定されたISO 8601の時間隔文字列が値の$intervalDaySecond |
値がSQLファンクションto_yminterval に指定されたISO 8601 interval文字列の$intervalYearMonth |
yearmonthInterval | INTERVAL YEAR TO MONTH |
string |
値がSQLファンクションto_yminterval に指定されたISO 8601 interval文字列の$intervalYearMonth |
2つのフィールド:
|
vector | VECTOR |
数値の配列 |
2つのフィールド:
|
脚注4 文字列値は大/小文字が区別されずに解釈されます。たとえば、"NAN"
、"nan"
および"nAn"
は受け入れられ同等であり、"INF"
、"inFinity"
および"iNf"
も同様です。無限に大きい("Infinity"
または"Inf"
)および小さい("-Infinity"
または"-Inf"
)数値は、フルワードまたは略称のいずれかで受け入れられます。
脚注5 出力では、これらの文字列値のみが使用されます。完全な単語のInfinityや大小文字の変形は使用されません。
2.2.6 JSONデータ型の値の比較とソート
SQLデータ型JSON
の値に対する正規のソート順について説明します。すべてのJSON値を比較するために使用されます。
スカラー、オブジェクト、配列のいずれであっても、任意の種類のJSON
データ型の値を直接比較またはソートできます。つまり、JSON
型はWHERE
句、ORDER BY
句またはGROUP BY
句で直接使用できるということです。正規のソート順序は、すべてのJSON
型の値(テキストJSON入力でOracle拡張オブジェクト・パターンから導出されたスカラー値を含む)にわたって定義されます。
ノート:
vector型のJSON言語スカラー値は、まず数値のJSON配列に変換されてから比較またはソートされます。結果の配列が比較またはソートされる値です。
ノート:
JSON
データ型の値をSQLで比較する場合、比較する値のサイズ(SQL比較用にエンコードされた値)は32Kバイト未満である必要があります。そうでない場合は、エラーが発生します。実際には、この比較用にエンコードされたSQLサイズは、同じJSONデータのテキスト表現のサイズとほぼ同じです。
たとえば、この問合せでは、dept
およびname
フィールドのエンコードされたサイズは、それぞれ32K未満である必要があります。
SELECT *
FROM emp t
WHERE t.data.dept = 'SALES' ORDER BY t.data.name
この制限は、SQL句ORDER BY
およびGROUP BY
、およびSQL値比較演算子(WHERE
句の>
など)の使用に適用されます。
より正確には、制限はSQL自体で行われる比較およびソートにのみ適用されます。JSON言語内で実行される比較またはソートには適用されません。つまり、json_transform
やjson_exists
など、JSONのSQL演算子によって実行される比較またはソートにサイズ制限はありません。特に、この制限はSQL/JSONパス式での比較には適用されません。
JSON
型のソート(比較)の順序は次のとおりです。脚注6
-
スカラー値は、非スカラー値の前に(キーワード
DESC
では後に)ソートされます。 -
オブジェクトは、配列の前に(キーワード
DESC
では後に)ソートされます。 -
2つの配列は、要素を順番に比較してソートされます。対応する2つの要素が等しくない場合は、それらの要素のソート順によって2つの配列の順序が決まります。たとえば、昇順ソートでは、
[4, 2, 5]
は[4, 2, 9]
より前にソートされます。これは、5
が9
より前にソートされるためです。1つの配列のすべての要素が、それより長い配列の対応する要素と等しい場合は、短い配列が長い配列の前にソートされます。たとえば、昇順ソートでは、
[4, 2]
は[4, 2, 5]
の前にソートされますが、[4, 1, 5]
の後にソートされます。 -
2つのオブジェクトは、次に示すように、フィールド名、フィールド値の順にソートされます。
-
各オブジェクトのメンバーは、フィールド名の順に並べられます。
フィールド名はJSON
string
の値として比較され、AL32UTF8文字セットで表されるVARCHAR2
照合とバイナリ順序が使用されます。 -
ソートされたオブジェクトのメンバー(ステップ1から)は、次の順序で比較されます。
-
2つの対応するフィールド名が異なる場合、最初にソートされるフィールド名を持つオブジェクトは、もう一方のオブジェクトの前に(キーワード
DESC
では後に)ソートされます。 - 2つの対応するフィールド名が同じ場合は、
JSON
型のソート順に従ってフィールドの値が比較されます。(つまり、フィールドの値は再帰的に比較されることになります)。2つの比較するオブジェクトの順序は、そのフィールド値の順序に従います。
-
-
-
2つの異なる型ファミリのスカラーは、この昇順でファミリごとにソートされるため、文字列の前に数値がソートされます。(降順ソートの場合は、順序が逆になります)。
null
- 数値(
number
、double
、float
) string
- 非識別子
binary
(例: 画像) - 識別子
binary
(例: フィールド$oid
または$rawid
を含む拡張オブジェクトからの値) boolean
- 日付と時点(
date
、timestamp
またはtimestamp with time zone
) yearmonthInterval
daysecondInterval
日時間隔値とバイナリ値は別々に比較およびソートする必要があるため、それら両方には2つの別々のファミリがあります。月ごとに異なる日数を設定できます。識別子として使用されるバイナリ値は、通常は、等価性をテストされます。等価性テストは通常は、実行可能な場合でも、非識別子のバイナリ値には役立ちません。
-
2つの同じ型ファミリのスカラーは、そのファミリに定義されたソート順でソートされます。たとえば、昇順ソートでは、
100
は使用する数値型とは無関係に200.0
の前にソートされ、"cat"
は使用する文字セットとは無関係に"dog"
の前にソートされます。使用されるスカラーJSON比較は対応するSQLスカラー型の照合ですが、JSONの
string
比較では、AL32UTF8文字セットで表されるバイナリ順でVARCHAR2
照合が使用されます。boolean
値の場合、false
はtrue
の前に(キーワードDESC
では後に)ソートされます。
ORDER BY
で実行するようなソートの目的でJSON
型の任意の値を比較できます。ただし、比較フィルタ条件など、他の目的での比較はより限定されます。
ソートは別として、同じ型ファミリ内の任意の値を比較できます。異なる型ファミリの値は常に等しくありません。等価性比較(==
)はfalseを生成し、非等価性比較(!=
、<>
)はtrueを生成します。<
、<=
、>=
および>
の比較は、同じファミリ内でのみ意味があり、有用です。異なるファミリの値とともに使用すると、比較条件はfalseを返します。たとえば、JSONオブジェクト、数値またはブール値は、JSON配列、文字列または日付より大きくも小さくもありません。
ヒント:
json_scalar
は、デフォルトでは非スカラー入力に対してNULL
を返し、非スカラーJSON値が関与する比較はスカラーとスカラーの比較よりもコストがかかることがあるため、JSONデータの順序付けや比較の際には、json_scalar
でラップした後に簡単な手動最適化を実施することで、比較対象のデータから非スカラーを効率的にプルーニングできます。(より正確には、すぐに比較されるNULL
に置換します)。
たとえば、次のようなコードがあるとします。
SELECT data FROM customers c
ORDER BY c.data.revenue;
次を使用します:
SELECT data FROM customers c
ORDER BY json_scalar(c.data.revenue);
項目メソッドtype()
を使用するとJSON値の型ファミリを特定でき、これは比較や索引付けの目的に役立ちます。ただし、これによって提供されるのは、それについての大まかなガイドのみです(通常は、JSON値の導出元となった、またはJSON値をマップできるSQLデータ型に関してのみレポートされるため)。
-
null
型ファミリ:type()
では"null"が返されます。 -
数値型ファミリ:
type()
では、数値の種類に応じて異なる型名が返されます。-
"double": SQLの
BINARY_DOUBLE
値に対応するJSON値(数値)の場合。これに含まれるのは、たとえば、$numberDouble
の拡張オブジェクトから導出された値です。 -
"float": SQLの
BINARY_FLOAT
値に対応するJSON値(数値)の場合。これに含まれるのは、たとえば、$numberFloat
の拡張オブジェクトから導出された値です。 -
"number": (1)テキストJSON数値か文字列数値(標準のJSON言語数値型に対応)、または(2)
$numberInt
、$numberDecimal
または$numberLong
の拡張オブジェクトから導出されたJSON値(数値)の場合。
-
string
型ファミリ:type()
では"string"が返されます。-
バイナリ型ファミリ:
type()
では、識別子および非識別子バイナリ・ファミリのどちらの場合も(つまり、SQLのRAW
値に対応する値)、"binary"が返されます。type()
では、これら2つのファミリの値を区別できません。 -
boolean
型ファミリ:type()
では"boolean"が返されます。 -
日付と時点ファミリの場合は、種類に応じて異なる型名が返されます。
-
"date": SQLの
DATE
値に対応する値の場合。これに含まれるのは、たとえば、$oracleDate
の拡張オブジェクトから導出された値です。 -
"timestamp": SQLの
TIMESTAMP
値に対応する値の場合。これに含まれるのは、たとえば、$oracleTimestamp
の拡張オブジェクトから導出された値です。 -
"timestamp with time zone": SQLの
TIMESTAMP WITH TIME ZONE
値に対応する値の場合。これに含まれるのは、たとえば、$date
または$oracleTimestampTZ
の拡張オブジェクトから導出された値です。($date
フィールドでは、小数秒を使用でき、協定世界時(UTC)の値が指定されるため、タイムゾーン付きタイムスタンプ値が格納されます。)
-
-
yearMonthInterval
型ファミリ: SQLのINTERVAL YEAR TO MONTH
値に対応する値の場合、type()
では"yearmonthInterval"が返されます。これに含まれるのは、たとえば、$intervalYearMonth
の拡張オブジェクトから導出された値です。 -
daysecondInterval
型ファミリ: SQLのINTERVAL DAY TO SECOND
値に対応する値の場合、type()
では"daysecondInterval"が返されます。これに含まれるのは、たとえば、$intervalDaySecond
の拡張オブジェクトから導出された値です。 -
vector
型ファミリ:type()
は"vector"を返します。脚注6
関連トピック
関連項目:
Oracle Databaseで各データ型の値が比較される方法の詳細は、『Oracle Database SQL言語リファレンス』のデータ型比較のルールに関する項を参照してください
親トピック: JSONデータ型
2.2.7 SQL値とJSONデータ型値の比較
JSON
型値をJSON
以外の型のSQL値と比較するとき、同じファミリの2つのJSON
型値(数値など)を比較するときと同じルールが適用されます。ただし、SQL型がそのファミリのJSON言語型のいずれかに対応しているという前提です。
(2つのJSON
型値の比較については、「JSONデータ型の値の比較とソート」を参照してください。)
これは、JSON値とSQL値の間で直接行われる唯一の有用な比較です。他のこのような比較ではすべて、単にfalseが返されるか、(例外的に)エラーが発生します。
たとえば、列DATA
がJSON
型であるとすると、これはJSON
型の数値とSQL NUMBER
値の有用な比較です。
SELECT c.data FROM customers
ORDER BY c.data.address.zip <= 12345;
この問合せは、実際には次の問合せと同等です:
SELECT c.data FROM customers
ORDER BY c.data.address.zip.numberOnly() = 12345;
このような比較をtrueにできるのは、JSON数値のみです。フィールドzip
の値が数値でない場合、つまり数値ファミリに属していない場合、比較はfalseを返します。たとえば、zip
が文字列"314"
の場合、比較はfalseになります。文字列"314"
を数値314
に変換する型変換は自動的に実行されません。
比較するSQL値がJSON言語スカラー型に対応する型でない場合、エラーが発生します。
たとえば、SDO_GEOMETRY
値はJSON値と直接比較できません:
ERROR at line 1:ORA-00932: expression is of data type
MDSYS.SDO_GEOMETRY, which is incompatible with expected data type JSON
比較対象のJSON値が非スカラー(オブジェクトまたは配列)の場合、比較はSQL値に関係なくfalseを返します。
JSON
型値のJSON言語型が不明で、比較対象のSQL値と互換性のある型に(可能なときは)変換する場合、型変換項目メソッドを使用できます(「データ型変換の項目メソッド」を参照してください)。
たとえば、この問合せでは、項目メソッドnumber()
を使用して、RETURNING NUMBER
句を指定したファンクションjson_value
と同様にフィールドzip
の値を解釈するため、zip
JSON文字列"314"
はJSON数値314
に変換されます(比較はtrueです)。
SELECT data FROM customers
ORDER BY c.data.address.zip.number() = 12345
ヒント:
JSONデータ・ガイドを使用して、不明なJSONデータ内の値のデータ型を特定できます。
比較対象のSQL値がJSON値を表す文字列である場合、JSON
コンストラクタを使用してJSON
型値に変換できます。これにより、スカラーか非スカラーかに関係なく、どのJSON値でも比較できます。(実際には、これはJSON値とSQL値を比較するケースではありません。)
たとえば、この問合せでは、JSON
型のフィールドzip
の値を、コンストラクタがSQL文字列'12345'
から解析したJSON
型の数値12345
と比較します。
SELECT c.data FROM customers
ORDER BY c.data.address.zip <= JSON('12345');
また、この問合せでは、フィールドaddress
の値を、次に示すリテラルJSONオブジェクトと比較します:
SELECT c.data FROM customers
ORDER BY c.data.address <=
JSON('{"street" : "200 Sporting Green",
"city" : "South San Francisco",
"state" : "CA",
"zipCode" : 99236');
比較対象のJSON値がテキスト(JSON
型ではない)の場合、比較ではSQL文字列(VARCHAR2
)として扱われます。
たとえば、列textualjson
が型VARCHAR2
で、フィールドzipの値がJSON数値314
の場合、314
が12345
より辞書的に大きいため、この比較はfalseです。
SELECT c.textualjson FROM customers
ORDER BY c.textualjson.address.zip <= '12345';
JSON数値はSQL文字列'314'
に変換され、SQL文字列'12345'
と比較されます(数値比較ではなく文字列比較)。
親トピック: JSONデータ型
脚注の凡例
脚注1: キーワードASCII
、PRETTY
、ORDERED
、TRUNCATE
およびEXTENDED
はOracleの拡張機能であり、SQL/JSON標準には含まれません。脚注6: スカラー・ベクター値はスカラーとして処理されないことに注意してください。かわりに、比較目的では数値の配列として処理されます。