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スキーマに関して整形式かつ有効であること
(またはでないこと
)を確認するためにテストされます。キーワードVALIDATE
(オプションでキーワードUSING
が続く)の後には、検証対象のJSONスキーマであるSQL文字列リテラルが続く必要があります。
JSON
型データの場合、データがオブジェクト、配列またはスカラー値であることのみをチェックする単純なJSONスキーマでVALIDATE
を使用するかわりに、キーワードOBJECT
、ARRAY
またはSCALAR
をそれぞれ使用できます。たとえば、次の条件は、データがオブジェクトであるかどうかをテストします:
is json OBJECT
修飾子キーワードSCALAR
の後には、スカラーの必要な型を指定するキーワードBOOLEAN
、BINARY
、BINARY_DOUBLE
、BINARY_FLOAT
、DATE
、INTERVAL DAY TO SECOND
、 INTERVAL YEAR TO MONTH
、NULL
、NUMBER
、STRING
、TIMESTAMP
またはTIMESTAMP WITH TIME ZONE
を続けることができます。
また、複数のJSON
型修飾子を使用することもできます。その場合は、カンマで区切ってリストをカッコで囲みます。たとえば、(OBJECT, SCALAR DATE)
ではオブジェクトまたは日付のみが許可され、次の2つの等価条件では、データがオブジェクトまたはスカラー値のどちらであるかがテストされます:
is json (OBJECT, SCALAR)
is not json ARRAY
ノート:
is json
でのJSON
型修飾子の使用は、JSON
型列の作成時にそれを使用する場合よりも制限されています。is json
の場合:
-
修飾子キーワード
LIMIT
は使用できません。 -
修飾子キーワード
ARRAY
の後に続けて、構文をカッコで囲んで、使用可能な配列値をさらに指定することはできません。
JSON
型修飾子キーワードを他のキーワードと組み合せて使用できます。(修飾子キーワードが最初に来る必要があります。)ただし、修飾子キーワードの効果が、is json SCALAR DISALLOW SCALARS
の指定など、存在する他のキーワードの効果と競合する場合は、エラーが発生します。
is json
がチェック制約として使用されている場合、JSON
型修飾子キーワードは使用できません:
CREATE TABLE t1 (c1 JSON CHECK (c1 is json OBJECT));
CREATE TABLE t1 (c1 JSON CHECK (c1 is json OBJECT))
*
ERROR at line 1:
ORA-02252: check constraint condition not properly ended
is
(not
) JSON
条件の解析(または検証)中にエラーが検出された場合、エラーが発生することはなく、データは整形式でない(または有効でない)とみなされます。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
でキーワードSTRICT
を指定する場合を除きます。指定する場合は、データがJSONデータであることを宣言する意味があり、ユーザーがそれを保証するため、整形式であるかどうかはチェックされません) -
SQLファンクション
json_serialize
の使用 -
SQL/JSONファンクション
json_query
の使用 -
FORMAT JSON
を指定したSQL/JSONファンクションjson_table
の使用 -
PL/SQL DOMでのPL/SQLメソッド
to_clob()
、to_blob()
またはto_string()
の使用
ノート:
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言語リファレンス』の「IS JSON条件」を参照してください。 -
JSONスキーマの詳細は、json-schema.orgを参照してください
- JSONオブジェクトの一意フィールドと重複フィールド
JSON標準では、JSONオブジェクトに重複するフィールド名がないことが推奨されています。Oracle Databaseでは、エラーを発行することでJSON
型のデータに対してこれが強制されます。テキスト形式で格納されている場合は、キーワードWITH UNIQUE KEYS
を指定したis json
チェック制約を使用して、重複するフィールド名を許可しないことをお薦めします。 - 厳密なJSON構文と緩慢なJSON構文
入力時には、JSONのOracleデフォルト構文は緩慢です。この構文は、オブジェクト・フィールドに対してJavaScript構文を反映し、ブール型の値およびnull
値では大/小文字が区別されず、数字、ホワイトスペースおよびUnicode文字のエスケープについてはより寛容です。Oracleは、標準に厳密に準拠したJSONデータを出力します。 - 条件IS JSONでの厳密なJSON構文の指定
Oracle Databaseでは、デフォルトで、JSONデータの解析時に緩慢な構文が使用されます。必ずテキストJSONデータが厳密になるようにするには、キーワード(STRICT)
(カッコを含む)を指定して条件is 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データを出力します。
標準IETF RFC 8259、ECMA 404およびECMA 262では、JSON構文が定義さています。Oracleでは、この厳密なJSON構文がサポートされており、出力時には必ずそれが使用されますが、入力時にデータを解析するときは緩慢な構文が使用されます。
これらの仕様(ECMAScript第5.1版より前)によると、各JSONフィールドおよび各文字列値は、二重引用符("
)で囲む必要があります。しかしながら、JavaScript表記法では、オブジェクト・リテラルで使用されるフィールドは二重引用符で囲むことはできますがそれは必須ではありません。これはまた、一重引用符('
)で囲むこともできます。
ECMA 262, 5.1 Editionでは、このようなフィールドを許可するなど、いくつかの方法で厳密な構文が緩和されました。Oracleの緩慢なJSON構文では、ECMAScript 5.1で指定されている構文がサポートされています。より一般的に述べると、Oracleの緩慢な構文では、一重引用符は二重引用符と同様に、複数の文字列を区切るための文字です。
また、Oracleの緩慢な構文では、ECMAScript 5.1で指定されている内容とは異なり、エスケープされていない行および段落セパレータ文字(U+2028およびU+2029)をJSON文字列に含めることができます。(これはJSON5の場合も同様で、この違いを除けば、ECMAScript 5.1の適切なサブセットです。)
さらに、実際には、一部のJavaScript実装では次の1つ以上が許可されています:
-
true
、false
およびnull
の大/小文字の相違(TRUE
、True
、TrUe
、fALSe
、NulL
など)。 -
配列の最後の要素またはオブジェクトの最後のメンバーの後に追加される単一のカンマ(
,
) ([a, b, c
,
]
、{a:b, c:d
,
}
など)。(これは、ECMAScript 5.1でも許可されます。) -
先頭に1つ以上の0がある数字(
0042.3
など)。 -
小数点の前に
0
がない小数(0.14
ではなく.14
など)。 -
小数点の後に小数部分がない数字(
342.
や1.e27
など)。 -
数値がマイナスではないことを意味する、数字の前のプラス記号(
+
) (+1.3
など)。
この構文も、Oracleの緩慢なJSON構文の一部として、入力時に許可されます。(厳密な数字構文は、JSON標準を参照してください。)
ASCIIのスペース文字(10進数の32、U+0020)以外にも、JSON標準では、引用符で囲まれたフィールドまたは文字列値の外側で使用される場合、次のASCII文字は重要でないホワイトスペース(つまり無視される)として定義されています。
-
タブ、水平タブ(
HT
、^I
、10進数の9、U+0009、\t
) -
行送り、改行(
LF
、^J
、10進数の10、U+000A、\n
) -
キャリッジ・リターン(
CR
、^M
、10進数の13、U+000D、\r
)
ただし、Oracleの緩慢なJSON構文では、すべてのASCII制御文字(制御文字0-31)は重要でないホワイトスペースとして処理されます。制御文字には次のようなものがあります。
-
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の厳密なJSON構文では、すべてのASCIIのホワイトスペース文字は重要でないものとして扱われ、ASCIIのスペース文字(U+0020)は、引用符で囲まれたフィールドまたは文字列値内で許可され、エスケープされない唯一のホワイトスペース文字です。Oracleの緩慢な構文では、ECMAScript 5.1と同様に、すべてのUnicodeのホワイトスペース文字は重要でないものとして扱われます。
Oracleの緩慢なJSON構文では、引用符で囲まれていないオブジェクト・フィールド名に、次を除いたエスケープされていないUnicode文字を含めることができます(ただし、エスケープ・シーケンスは許可されません):
-
ホワイトスペース、つまりホワイトスペース・プロパティを持つUnicode文字。『Unicode character property, Whitespace』を参照してください。
-
JSON構造文字: 左右の角カッコ(
[
、]
)および波カッコ({
、}
)、コロン(:
)およびカンマ(,
)。 -
斜線(スラッシュとも呼ばれる、
/
)。これは、/*
がECMAScript 5.1とOracleの緩慢な構文の両方でJSONコメント(*/
で終了)を開始するため、許可されません。 -
逆斜線(バックスラッシュとも呼ばれる、
\
)。これはエスケープ・シーケンスを導入するため、許可されません。 -
一重引用符および二重引用符(
'
、"
)。これらは文字列デリミタとして機能するため、許可されません。
厳密な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文字が許可されます。これには、ホワイトスペース文字と、コロン( |
|
緩慢(および厳密): いいえ。引用符で囲まれている名前では、構造文字は許可されません。 |
ノート:
このドキュメントでは次の2つの異なる方法で"厳密"と"緩慢"が使用されています。これらを混同しないでください:
-
厳密または緩慢な構文のチェック。これは、入力時などの、テキストJSONデータの解析方法について言及しています。
厳密な構文では、JSON標準が完全に尊重されます。緩慢な構文では、引用符なしのフィールド名が許可されているなど、いくつかの点で標準から逸脱したデータが受け入れられます。
厳密な構文と緩慢な構文については、「厳密なJSON構文と緩慢なJSON構文」を参照してください。
-
厳密または緩慢な型互換性。これは、JSON値をそれらのJSON言語型に関して厳密に比較するかどうかに言及しています。
厳密な型互換性では、値が、想定している型と同じJSON言語型ファミリである必要があります。たとえば、想定している型が
number
である場合、互換性のある値は、数値である必要があります。緩慢な型互換性では、値を、想定している型に変換しようとします。たとえば、文字列"42"
は、型number
と緩慢な互換性があります。厳密な型互換性と緩慢な型互換性については、「SQLファンクションおよび条件のTYPE句」を参照してください。
関連項目:
-
JSONデータ交換フォーマットの定義は、ECMA404およびIETF RFC 8259のサイトを参照してください
-
ECMAScript言語仕様(JavaScript)の場合は、ECMA 262およびECMA 262第5.1版
-
JSONおよびJavaScriptの詳細は、JSON.org、JSON5およびECMA Internationalを参照してください
5.3 条件IS JSONでの厳密なJSON構文の指定
Oracle Databaseでは、デフォルトで、JSONデータの解析時に緩慢な構文が使用されます。必ずテキストJSONデータが厳密になるようにするには、キーワード(STRICT)
(カッコを含む)を指定して条件is json
を使用します。
例5-1 テキストのJSONデータが厳密な整形式であることを確認するためのチェック制約でのIS JSONの使用
JSON列data
のデータ型はVARCHAR2
です。そのデータはテキストであるため(JSON
型ではない)、is json
チェック制約が必要です。キーワードSTRICT
は、厳密な(つまり、標準)JSON構文であることを必須とするために使用されています。脚注1
CREATE TABLE j_purchaseorder
(id VARCHAR2 (32) NOT NULL PRIMARY KEY,
date_loaded TIMESTAMP (6) WITH TIME ZONE,
data VARCHAR2 (32767)
CONSTRAINT ensure_json CHECK (data is json (STRICT)));
キーワードSTRICT
の追加を除き、これは例4-2と同じです(その例では、整形式のJSONデータを必要としているが、その構文は緩慢でも厳密でもかまわない)
関連トピック
関連項目:
『Oracle Database SQL言語リファレンス』の「CREATE TABLE」
脚注の凡例
脚注1:IS NOT JSON (STRICT)
を使用すると、一部のテキスト・データが厳密に整形式のJSONではないことをチェックできます。