5 SQL/JSON条件IS JSONおよびIS NOT JSON
SQL/JSON条件is json
およびis not json
は補足的な条件です。これらは、引数が構文的に正しい(つまり、整形式の)JSONデータかどうかをテストします。これらは、SELECT
文のCASE
式またはWHERE
句で使用できます。is json
はチェック制約で使用できます。
引数が構文的に正しい場合、is json
はtrueを戻し、is not json
はfalseを戻します。
解析中にエラーが発生した場合、エラーは発生せず、データは整形式ではないとみなされます。is json
はfalseを返し、is not json
はtrueを返します。解析中以外にエラーが発生した場合は、そのエラーが発生します。
整形式のデータとは、構文的に正しいデータであることを意味します。テキストとして格納されているJSONデータは、厳密な構文と緩慢な構文と呼ばれる2つの意味での整形式にすることができます。また、テキストのJSONデータの場合は、JSONオブジェクトに重複したフィールド(キー)を含めることができるかどうかを指定できます。任意の型のJSONデータについて、整形式のデータの文書に最上位レベルのスカラー値を含めることができるかどうかを指定できます(データベース初期化パラメータcompatible
が20
以上の場合)。
テキストのJSONデータがデータベース内で生成される場合は、キーワードSTRICT
を指定した条件is json
を満たします。これには次の方法による生成が含まれます。
-
SQL/JSON生成関数を使用(
FORMAT JSON
またはTREAT AS JSON
にキーワードSTRICT
を指定しない場合。このキーワードには、データがJSONデータであることを宣言する意味があり(ユーザーがそれを保証します)、整形式であるかどうかはチェックされません) -
SQLファンクション
json_serialize
の使用 -
PL/SQL DOMでのSQLファンクション
to_clob
、to_blob
またはto_varchar2
の使用 -
SQL/JSONファンクション
json_query
の使用 -
FORMAT JSON
を指定したSQL/JSONファンクションjson_table
の使用
注意:
JSON
型のデータは一意のオブジェクト・キー(フィールド名)のみを持ち、厳密な構文と緩慢な構文の概念は適用されません。(任意のデータ型の) JSONデータをシリアライズしてテキストのJSONデータを生成する場合、結果の構文は常に厳密です。
JSON
データ型を使用してJSONデータを格納し、is json
チェック制約を使用する場合、次のようになります。
-
キーワード
DISALLOW SCALARS
を指定した場合、JSON列には最上位レベルのスカラーJSON値を持つ文書を格納できません。 -
キーワードを指定しない場合、または
DISALLOW SCALARS
以外のキーワードを指定した場合、is json
制約は無視されます。それらのキーワードでは何も変更されません。
関連項目:
is json
およびis not json
の詳細は、Oracle Database SQL言語リファレンスを参照してください。
- JSONオブジェクト内の一意のフィールドと重複したフィールド
標準では特定のJSONオブジェクトのフィールド名を一意にすることを求めていませんが、JSON
型を使用してデータを格納する場合、重複したフィールドは(警告なしで)削除されます。テキストとして格納されたJSONデータに重複したフィールド名がある場合、それを整形式とみなすかどうかを制御できます。 - 厳密なJSON構文と緩慢なJSON構文について
JSON向けのOracleのデフォルト構文は緩慢です。特に、この構文は、オブジェクト・フィールドに対してJavaScript構文を反映し、ブール型の値およびnull
値では大/小文字が区別されず、数字、ホワイトスペースおよびUnicode文字のエスケープについてはより寛容です。 - 厳密なJSON構文と緩慢なJSON構文の指定
Oracle Database向けのデフォルトのJSON構文は緩慢です。構文が厳密か緩慢かが問題になるのは、SQL/JSON条件is json
およびis not json
の場合のみです。他のすべてのSQL/JSONファンクションおよび条件では、入力を解析するために緩慢な構文が使用され、出力を戻すために厳密な構文が使用されます。
親トピック: JSONデータの格納および管理
5.1 JSONオブジェクトの一意フィールドと重複フィールド
標準では特定のJSONオブジェクトのフィールド名を一意にすることを求めていませんが、JSON
型を使用してデータを格納する場合、重複したフィールドは(警告なしで)削除されます。テキストとして格納されたJSONデータに重複したフィールド名がある場合、それを整形式とみなすかどうかを制御できます。
先験的に、整形式のJSONオブジェクトは、同じフィールド名を持つ複数のメンバーを持つことができます。JSON標準ではそうできないとは指定されていません。
テキストで格納されるデータ(VARCHAR2
、CLOB
、BLOB
)の場合、デフォルトの動作ではそのような重複キー(フィールド名)が許可されますが、これは単に重複する名前をチェックすると追加の時間がかかるためです。
ただし、Oracle Databaseで採用されている評価では常に、特定のフィールド名を持つオブジェクト・メンバーの1つのみが使用されます。同じフィールド名を持つ他のメンバーは無視されます。このような複数のメンバーのうちどれが使用されるかは指定されていません。
テキストで格納されたJSONデータのデフォルトの動作をオーバーライドして、重複するキーを持つオブジェクトを含むデータを挿入しようとしたときにエラーが発生するようにできます。これを行うには、キーワードWITH UNIQUE KEYS
を指定してis json
チェック制約を使用します。
JSON
型の列に挿入するデータに重複キーがある場合、どのキーが保持されるかは同様に指定されません。使用するフィールドを制御する必要がある場合は、データを前処理して使用しないフィールドを削除してから、JSON
型の列に挿入します。WITH UNIQUE KEYS
を指定しても、JSON
型の列に挿入されるデータには影響しません。キーが重複するデータに対して、エラーは発生しません。
整形式のJSONデータで重複フィールド名が許可されるかどうかは、整形式かどうかの確認に、厳密な構文と緩慢な構文のどちらが使用されるかとかかわっています。
5.2 厳密なJSON構文と緩慢なJSON構文について
JSON向けのOracleのデフォルト構文は緩慢です。特に、この構文は、オブジェクト・フィールドに対してJavaScript構文を反映し、ブール型の値およびnull
値では大/小文字が区別されず、数字、ホワイトスペースおよびUnicode文字のエスケープについてはより寛容です。
標準ECMA-404のJSONデータ交換フォーマット、およびECMA-262のECMAScript言語指定により、JSON構文が定義されます。
これらの指定に応じて、各JSONのフィールドおよび各文字列値は、二重引用符("
)で囲む必要があります。Oracleではこの厳密なJSON構文をサポートしていますが、これはデフォルトの構文ではありません。
JavaScript表記法では、オブジェクト・リテラルで使用されるフィールドは、二重引用符で囲むことができますが、必須ではありません。これはまた、一重引用符('
)で囲むこともできます。Oracleではこの緩慢なJSON構文もサポートしており、これがデフォルトの構文です。
また、実際に、一部のJavaScript実装(ただし、JavaScript標準ではありません)では次の1つ以上が許可されています。
-
キーワード
true
、false
およびnull
の大/小文字の相違(TRUE
、True
、TrUe
、fALSe
、NulL
など)。 -
配列の最後の要素またはオブジェクトの最後のメンバーの後ろに追加されるカンマ(
,
) ([a, b, c
,
]
、{a:b, c:d
,
}
など)。 -
先頭に1つ以上の0がある数字(
0042.3
など)。 -
小数点の前に
0
がない小数(0.14
ではなく.14
など)。 -
小数点の後に小数部分がない数字(
342.
や1.e27
など)。 -
数値がマイナスではないことを意味する、数字の前のプラス記号(
+
) (+1.3
など)。
この構文も、Oracleのデフォルトの(緩慢な) JSON構文の一部として許可されます。(厳密な数字構文は、JSON標準を参照してください。)
ASCIIのスペース文字(U+0020)以外にも、JSON標準では、引用符で囲まれたフィールドまたは文字列値の外側で使用される場合、次の文字は重要でない(無視される)ホワイトスペースとして定義されています。
-
タブ、水平タブ(
HT
、^I
、10進数の9、U+0009、\t
) -
行送り、改行(
LF
、^J
、10進数の10、U+000A、\n
) -
キャリッジ・リターン(
CR
、^M
、10進数の13、U+000D、\r
)
ただし、JSONの緩慢な構文では、ASCII制御文字(0-31)のすべて、およびASCIIスペース文字(10進数の32、U+0020)は(重要でない)ホワイトスペース文字として処理されます。制御文字には次のようなものがあります。
-
Null (
NUL
、^@
、10進数の0、U+0000、\0
) -
ベル(
NEL
、^G
、10進数の7、U+0007、\a
) -
垂直タブ(
VT
、^K
、10進数の11、U+000B) -
エスケープ(
ESC
、^[
、10進数の27、U+001B、\e
) -
削除(
DEL
、^?
、10進数の127、U+007F)
ASCIIのスペース文字(U+0020)は、引用符で囲まれたフィールドまたは文字列値内で許可されてエスケープされていない唯一のホワイトスペース文字です。これは、厳密なJSON構文と緩慢なJSON構文の両方に対して当てはまります。
厳密なJSON構文と緩慢なJSON構文の両方において、引用符で囲まれたオブジェクト・フィールドおよび文字列値に含めることができるのはUnicode文字のみですが、これらの一部は次のようにエスケープする必要があります。
-
ASCII制御文字は許可されていませんが、
\b
(バックスペース)、\f
(フォーム・フィード)、\n
(改行、行送り)、\r
(キャリッジ・リターン)および\t
(タブ、水平タブ)の各エスケープ・シーケンスによって表される文字は除きます。 -
二重引用符(
"
)、スラッシュ(/
)およびバックスラッシュ(\
)文字もエスケープする(バックスラッシュを前に置く)必要があります(それぞれ\"
、\/
および\\
)。
緩慢なJSON構文では、引用符で囲まれていないオブジェクト・フィールドに、ホワイトスペースとJSON構造文字(左右の大カッコ([
、]
)と中カッコ({
、}
)、コロン(:
)およびカンマ(,
))を除く任意のUnicode文字を含めることができますが、エスケープ・シーケンスは許可されません。
名前または文字列にも任意のUnicode文字を含めることができますが、この場合、Unicodeコード・ポイントを表す4つのASCIIの16進数字を後ろに付けたASCIIのエスケープ構文\u
を使用します。
厳密なJSON構文と緩慢なJSON構文のいずれにおいても、出力可能でないかホワイトスペースとして表示される可能性がある他のUnicode文字(ノーブレークスペース文字(U+00A0)など)はホワイトスペースとみなされません。
表5-1は、JSON構文のいくつかの例を示しています。
表5-1 JSONオブジェクト・フィールドの構文例
例 | 整形式かどうか |
---|---|
|
緩慢および厳密: はい。スペース文字は許可されます。 |
|
緩慢(および厳密): いいえ。引用符で囲まれていない名前では、スペース文字を含むホワイトスペース文字は許可されません。 |
|
緩慢および厳密: はい。タブ文字のエスケープ・シーケンスは許可されます。 |
|
緩慢および厳密: いいえ。エスケープされていないタブ文字は許可されません。エスケープされていないホワイトスペース文字で許可されるのはスペースのみです。 |
|
緩慢および厳密: はい。名前が引用符で囲まれている場合、エスケープされている二重引用符は許可されます。 |
|
緩慢および厳密: いいえ。名前は引用符で囲む必要があります。 |
|
緩慢: はい、厳密: いいえ。一重引用符で囲まれた名前(オブジェクト・フィールドと文字列)は、緩慢な構文でのみ許可されます。引用符で囲まれた名前では、エスケープされている二重引用符が許可されます。 |
|
緩慢および厳密: はい。引用符で囲まれた名前では、任意のUnicode文字が許可されます。これには、ホワイトスペース文字と、コロン( |
|
緩慢(および厳密): いいえ。引用符で囲まれている名前では、構造文字は許可されません。 |
関連項目:
-
JSONデータ交換フォーマットの定義は、ECMA404およびIETF RFC 8259のサイトを参照してください
-
JSONおよびJavaScriptの詳細は、ECMA InternationalおよびJSON.orgを参照してください
5.3 厳密なJSON構文と緩慢なJSON構文の指定
Oracle Database向けのデフォルトのJSON構文は緩慢です。構文が厳密か緩慢かが問題になるのは、SQL/JSON条件is json
およびis not json
の場合のみです。他のすべてのSQL/JSONファンクションおよび条件では、入力を解析するために緩慢な構文が使用され、出力を戻すために厳密な構文が使用されます。
特定のテキストのJSONデータに厳密に正しい構文が使用されていることを確認する必要がある場合は、最初にis json
またはis not json
を使用してチェックしてください。
JSON標準に応じてデータを厳密な整形式としてチェックするよう指定するには、(STRICT)
(カッコを含む)をis json
またはis not json
式に追加します。
例5-1に、これを示します。これは例4-2と同じですが、列に挿入されたすべてのデータがJSON標準に応じた整形式であることを確認するために(STRICT)
が使用されています。
関連項目:
CREATE TABLE
の詳細は、Oracle Database SQL言語リファレンスを参照してください。
例5-1 テキストのJSONデータが厳密な整形式であることを確認するためのチェック制約でのIS JSONの使用
JSON列はデータ型VARCHAR2
です。この型はJSON
型ではないため、is json
チェック制約が必要となります。この例では、厳格な、つまり標準のJSON構文が指定されています。
CREATE TABLE j_purchaseorder
(id VARCHAR2 (32) NOT NULL PRIMARY KEY,
date_loaded TIMESTAMP (6) WITH TIME ZONE,
po_document VARCHAR2 (32767)
CONSTRAINT ensure_json CHECK (po_document is json (STRICT)));