5 SQL/JSON条件IS JSONおよびIS NOT JSON
SQL/JSON条件is json
およびis not json
は補足的な条件です。これらは、引数が構文的に正しい(つまり、整形式の)JSONデータかどうかをテストします。オプションのキーワードVALIDATE
によって、データが特定のJSONスキーマに関しても有効かどうかをテストします。
is json
とis not json
は、CASE
式またはSELECT
文のWHERE
句で使用できます。is json
はチェック制約で使用できます。
テストしたデータが構文的に正しいときに、キーワードVALIDATE
が存在しない場合、is json
はtrueを返し、is not json
はfalseを返します。
キーワードVALIDATE
が存在する場合、データは指定されたJSONスキーマに関して正しい形式であり有効であること(またはIS NOT
)を確認するためにテストされます。キーワードVALIDATE
(オプションでキーワードUSING
が続く)の後には、検証対象のJSONスキーマであるSQL文字列リテラルが後続している必要があります。
解析中(または検証中)にエラーが検出された場合は、エラーが発生することはなく、データが整形式ではない(または不正)とみなされます。is json
はfalseを返し、is not json
はtrueを返します。(解析中または検証中以外にエラーが検出された場合は、そのエラーが発生します)。
整形式のデータとは、構文的に正しいデータであることを意味します。テキストとして格納されているJSONデータは、厳密な構文と緩慢な構文と呼ばれる2つの意味での整形式にすることができます。また、テキストのJSONデータの場合は、JSONオブジェクトに重複したフィールド(キー)を含めることができるかどうかを指定できます。
anyデータ型(テキストまたはJSON
型)のJSONデータの場合:
-
整形式のデータの文書に最上位レベルのスカラー値を含めることができるかどうかを指定できます(データベース初期化パラメータ
compatible
が20
以上の場合)。また、有効である必要があることも指定できます。 -
特定のJSONスキーマに対して、データを検証する必要があること(または
IS NOT JSON
によって、その必要がないこと)を指定できます。
テキストの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_string
の使用 -
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
制約は無視されます。それらのキーワードでは何も変更されません。
キーワードCHECK
およびIS JSON
は省略できます。たとえば、次の2つのチェック制約は同等であり、どちらも、列jcol
の値がJSON文字列であることを確認します:
CHECK (jcol IS JSON VALIDATE '{"type": "string"}')
jcol VALIDATE '{"type": "string"}'
関連項目:
-
is json
およびis not json
の詳細は、Oracle Database SQL言語リファレンスを参照してください。 -
JSONスキーマの詳細は、json-schema.orgを参照してください
- JSONオブジェクトの一意フィールドと重複フィールド
JSON標準では、JSONオブジェクトに重複するフィールド名がないことが推奨されています。Oracle Databaseでは、エラーを発行することでJSON
型のデータに対してこれが強制されます。テキスト形式で格納されている場合は、キーワードWITH UNIQUE KEYS
を指定したis json
チェック制約を使用して、重複するフィールド名を許可しないことをお薦めします。 - 厳密なJSON構文と緩慢なJSON構文について
inputでは、JSONのOracleのデフォルト構文はlaxです。この構文は、オブジェクト・フィールドに対してJavaScript構文を反映し、ブール型の値およびnull
値では大/小文字が区別されず、数字、ホワイトスペースおよびUnicode文字のエスケープについてはより寛容です。Oracleは、標準に厳密に準拠したJSONデータを出力します。 - 厳密なJSON構文と緩慢なJSON構文の指定
Oracle Database向けのデフォルトのJSON構文は緩慢です。構文が厳密か緩慢かが問題になるのは、SQL/JSON条件is json
およびis not json
の場合のみです。他のすべてのSQL/JSONファンクションおよび条件では、入力を解析するために緩慢な構文が使用され、出力を戻すために厳密な構文が使用されます。
親トピック: JSONデータの格納および管理
5.1 JSONオブジェクトの一意フィールドと重複フィールド
JSON標準では、JSONオブジェクトに重複するフィールド名がないことが推奨されています。Oracle Databaseでは、エラーを発行することでJSON
型のデータに対してこれが強制されます。テキスト形式で格納されている場合は、キーワードWITH UNIQUE KEYS
を指定したis json
チェック制約を使用して、重複するフィールド名を許可しないことをお薦めします。
テキスト(VARCHAR2
、CLOB
、BLOB
列)で格納されている場合、重複する名前のチェックに時間がかかるため、デフォルトでは、JSONデータの重複するフィールド名が許可されています。テキストで格納されたJSONデータのこのデフォルトの動作によって一貫性のない動作になる可能性があるため、デフォルトには依存しないことをお薦めします。
このデフォルトの動作をオーバーライドして、フィールドが重複しているオブジェクトを含むデータを挿入しようとしたときにエラーが発生するようにできます。これを行うには、キーワードWITH UNIQUE KEYS
を指定してis json
チェック制約を使用します。(これらのキーワードは、JSON
型の列に挿入されるデータには影響しません。)
整形式のテキストJSONデータで重複フィールド名が許可されるかどうかは、整形式かどうかの確認に、厳密な構文と緩慢な構文のどちらが使用されるかとかかわっています。
5.2 厳密なJSON構文と緩慢なJSON構文について
入力時には、JSONのOracleのデフォルト構文は緩慢です。この構文は、オブジェクト・フィールドに対してJavaScript構文を反映し、ブール型の値およびnull
値では大/小文字が区別されず、数字、ホワイトスペースおよびUnicode文字のエスケープについてはより寛容です。Oracleは、標準に厳密に準拠したJSONデータを出力します。
標準ECMA 404のJSONデータ交換フォーマット、およびECMA 262のECMAScript言語仕様により、JSON構文が定義されます。
これらの仕様(ECMAScript第5.1版より前)によると、各JSONフィールドおよび各文字列値は、二重引用符("
)で囲む必要があります。Oracleはこの厳格なJSON構文をサポートしており、常に出力時にこの構文を尊重しますが、これは入力データのデフォルトの構文ではありません。
JavaScript表記法では、オブジェクト・リテラルで使用されるフィールドは、二重引用符で囲むことができますが、必須ではありません。これはまた、一重引用符('
)で囲むこともできます。ECMA 262第5.1版では、このようなフィールドを許可するなど、いくつかの方法で厳密な構文が緩和されました。Oracleでは、ECMAScript 5.1で指定されたこの構文がサポートされています。
デフォルトでは、Oracleは入力データを受け入れるときに緩慢なJSON構文を使用します。この構文は、ECMAScript 5.1で指定されている構文とは細部が1つ異なります。Oracleでは、エスケープされていない行および段落区切り文字(U+2028およびU+2029)をJSON文字列に含めることができます。(これはJSON5の場合も同様で、この違いを除けば、ECMAScript 5.1の適切なサブセットです。)
さらに、実際には、一部の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
)
ただし、Oracleの緩慢なJSON構文では、ASCII制御文字([Ctrl]+[0]から[Ctrl]+[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)
Oracleの厳密な構文(ECMAScript 5.1など)では、ASCIIスペース文字(10進数32、U+0020)以外のすべてのUnicodeホワイトスペースは重要でないものとして扱われます。また、厳密な構文では、U+0020は、引用符で囲まれたフィールドまたは文字列値内で許可され、エスケープされていない唯一のホワイトスペースです。
Oracleの緩慢なJSON構文では、引用符で囲まれていないオブジェクト・フィールドに、ホワイトスペースとJSON構造文字(左右の大カッコ([
、]
)と中カッコ({
、}
)、コロン(:
)およびカンマ(,
))を除く任意のUnicode文字を含めることができますが、エスケープ・シーケンスは許可されません。
厳密なJSON構文と緩慢なJSON構文の両方で、引用符で囲まれたオブジェクト・フィールドおよび文字列値に任意のUnicode文字を含めることができます。それぞれを含めるには、ASCIIエスケープ構文\u
の後にUnicodeコード・ポイントを表す4つのASCII 16進数を続けます。
次のUnicode文字は、\u
の後にコード・ポイントまたは特殊なエスケープ・シーケンスが続くフィールドおよび文字列で表される必要があります。
-
ASCII制御文字のバックスペース(CONTROL-H)、フォームフィード(CONTROL-L)、改行(行送り)、キャリッジリターン(CONTROL-M)、および(水平)タブ(CONTROL-I)。
\b
(バックスペース)、\f
(フォーム・フィード)、\n
(改行)、\r
(キャリッジリターン)および\t
(タブ)を使用します。 -
二重引用符(
"
)、スラッシュ(/
)およびバックスラッシュ(\
)文字。これらをエスケープするには、それぞれの前にバックスラッシュ文字
\"
、\/
、および\\
を付けます。
表5-1は、JSON構文のいくつかの例を示しています。
表5-1 JSONオブジェクト・フィールドの構文例
例 | 整形式かどうか |
---|---|
|
緩慢および厳密: はい。スペース文字は許可されます。 |
|
緩慢(および厳密): いいえ。引用符で囲まれていない名前では、スペース文字を含むホワイトスペース文字は許可されません。 |
|
緩慢および厳密: はい。タブ文字のエスケープ・シーケンスは許可されます。 |
|
緩慢: はい、厳密: いいえ。エスケープされていないタブ文字は、緩慢な構文でのみ使用できます。厳密な構文で許可されるエスケープされていないホワイトスペース文字は、スペース(U+0020)のみです。 |
|
緩慢および厳密: はい。名前が引用符で囲まれている場合、エスケープされている二重引用符は許可されます。 |
|
緩慢および厳密: いいえ。二重引用符を埋め込むには、フィールド名を引用符で囲む必要があります。 |
|
緩慢: はい、厳密: いいえ。一重引用符で囲まれた名前(オブジェクト・フィールドと文字列)は、緩慢な構文でのみ許可されます。引用符で囲まれた名前では、エスケープされている二重引用符が許可されます。 |
|
緩慢および厳密: はい。引用符で囲まれた名前では、任意のUnicode文字が許可されます。これには、ホワイトスペース文字と、コロン( |
|
緩慢(および厳密): いいえ。引用符で囲まれている名前では、構造文字は許可されません。 |
関連項目:
-
JSONデータ交換フォーマットの定義は、ECMA404およびIETF RFC 8259のサイトを参照してください
-
ECMAScript言語仕様(JavaScript)の場合は、ECMA 262およびECMA 262第5.1版
-
JSONおよびJavaScriptの詳細は、JSON.org、JSON5およびECMA Internationalを参照してください
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)));