18.7 SQLファンクションおよび条件のTYPE句

SQL条件json_existsと、ファンクションjson_transformjson_valuejson_queryおよびjson_tableではそれぞれ、オプションのTYPE句を受け入れます。この句により、JSON値をJSON言語型に関して厳密に(つまり、関連する"only"データ型変換項目メソッドが比較対象データに適用されたかのように)比較するかどうかが指定されます。

キーワードTYPEの後に、カッコで囲んだキーワードSTRICTまたはLAXが続きます。

  • TYPE (LAX)により、デフォルト動作である緩慢な型互換性を指定します(TYPE句なしと同じ)。これにより、JSON値を、比較のためにSQLデータ型の値として暗黙的に解釈(実質的にキャスト)できるようになります。この型キャストについては、「フィルタ条件比較における型」を参照してください。

    たとえば、'$.PONumber?(@ > 20)などの比較では、PONumber"314"が数値314として暗黙的に解釈されます(数値20と比較されるため)。この比較は、式が'$.PONumber?(@.number() > 20)の場合と同様にtrueです

  • TYPE (STRICT)により、厳密な型互換性を指定します。これは、"only"項目メソッドを適用するのと同じ効果があります。

    たとえば、'$.PONumber?(@ > 20)'$.PONumber?(@.numberOnly() > 20)であるかのように動作します。PONumber"314"の場合、式が'$.PONumber?(@.numberOnly() > 20)の場合と同様に比較はfalseです。

緩慢な型互換性は、json_transformjson_queryjson_valuejson_tableおよびjson_existsのデフォルト動作ですが、初期化パラメータJSON_BEHAVIORを次のオプションの任意の組合せを指定して使用し、現在のデータベース・セッションについて、このデフォルト動作を変更できます。各オプションは、TRUE (デフォルト値)またはFALSEとして指定できます。つまり、そのセッションのデフォルト動作として、それぞれ、緩慢な型互換性または厳密な型互換性を使用することを示します。

  • lax_json_value — ファンクションjson_valueのみに影響します。

  • lax_json_query — ファンクションjson_valueのみに影響します。

  • lax_json_table — ファンクションjson_tableのみに影響します。指定したデフォルトは、表のすべての列に適用されます。それらの特定のセマンティクス(json_valuejson_queryjson_exists)には関係ありません。

  • lax_json_exists — 条件json_existsとファンクションjson_transformの両方に影響します。

デフォルトでは、影響を受けるSQL演算子それぞれに対する型互換性チェックは緩慢です。これは、指定したオプションにTRUEの値を使用することに相当します。緩慢な型互換性とは、対象となっているデータが必須データ型でない場合はそれをそのデータ型に変換することを試みるということです。変換に失敗した場合、その演算子は、その演算子の現在のON ERROR動作に従います。これは、型が一致しなかった場合の厳密な型互換性の動作でもあります。

たとえば、指定したjson_value呼出しによって返された型がNUMBERであり、対象となっているデータが文字列"42"である場合は、緩慢な型互換性により、その値が数値42に変換されます。厳密な互換性ではそのような変換は実行されず、結果としてON ERROR動作が発生します。これは、デフォルトでは、条件json_existsの場合はFALSE ON ERROR、それらのファンクションの場合はNULL ON ERRORです。

パラメータjson_behaviorでは、デフォルトの型互換性動作のみを指定します。具体的に述べると、TYPE句の使用により、指定した演算子呼出しの実際の動作が決まるということです。

例18-3 パラメータJSON_BEHAVIORの使用による緩慢/厳密な型互換性の指定

各SQL演算子のデフォルトの型互換性は厳密に設定されているため、対象となっているデータが、必要な戻り型に変換されることはありません。厳密な型互換性の動作では、対象となっているデータが戻り型と一致しないと、デフォルトのON ERROR動作が発生します。

ALTER SESSION SET JSON_BEHAVIOR=
  "lax_json_value:false;lax_json_query:false;lax_json_table:false;lax_json_exists:false";

このjson_value問合せは、対象となっている文字列"42"を数値42に変換してそれを返すのではなく、NULLを返します。

SELECT json_value('{"a" : "42"}', '$.a' RETURNING NUMBER);

json_tableの場合、json_behaviorで強制適用された、デフォルトの厳密な型互換性が、すべての列に影響します。フィールドaは想定されている型であり、フィールドbはそうではありません。フィールドbの文字列値"42"を型NUMBERに変換することは試みません。列bについてはNULLを返します。

SELECT jt.* FROM json_table('{"a" : 314, "b" : "42"}',
                  '$' COLUMNS (a NUMBER PATH '$.a',
                               b NUMBER PATH '$.b')) jt;
A    B
---- ----
 314

このjson_query問合せは、数値42と等しい、配列aの要素を検索しています。緩慢な型互換性の場合、これは文字列要素"42"をその数値に変換し、配列[42, 6, "alpha"]を返します。しかしながら、厳密な型互換性の場合、これはNULL (何もない - 一致なし)を返します。

SELECT json_query('{"a" : [ 314, "42", "alpha" ]}',
                  '$.a?(@ == 42)');

このjson_exists問合せは、値が数値42または314であるフィールドbを検索しています。緩慢な型互換性の場合、これは文字列"42"を数値42に変換して、述語での42に一致させて、その結果、TRUEを返します。しかしながら、厳密な型互換性の場合は、入力データの変換は試みず、FALSEを返します。

SELECT json_exists('{"a" : {"b" : "42"}}',
                   '$.a?(@.b in (42, 314))');

このjson_transform問合せは、対象となっているオブジェクトにフィールドbを挿入し、それに、フィールドaの値に1を加えた値を与えています。緩慢な型互換性の場合、これは、aの文字列値"42"を数値(正) 42に変換して、bの値42+1=43を生成し、結果は、オブジェクト{"a":"42", "b":43}になります。しかしながら、厳密な型互換性の場合は、そのような変換を試みないため、フィールドbの値はJSON nullであり、結果は、オブジェクト{"a":"42", "b":null}になります。

SELECT json_transform('{"a" : "42"}',
                      INSERT '$.b' = PATH '$?(@.a > 0).a + 1');

SQL演算子どれかの呼出しにおいてTYPE(LAX)を使用すると、必ず、デフォルトの型互換性がオーバーライドされます。たとえば、デフォルトの型互換性が厳密である場合、この問合せでは、フィールドaの文字列値が数値42に正常に変換されます。

SELECT json_transform('{"a" : "42"}',
                      INSERT '$.b' = PATH '$?(@.a > 0).a + 1'
                      TYPE(LAX));
JSON_TRANSFORM(...)
-------------------
{"a":"42", "b":43}

ノート:

このドキュメントでは次の2つの異なる方法で"厳密"と"緩慢"が使用されています。これらを混同しないでください:

  • 厳密または緩慢な構文のチェック。これは、入力時などの、テキストJSONデータの解析方法について言及しています。

    厳密な構文では、JSON標準が完全に尊重されます。緩慢な構文では、引用符なしのフィールド名が許可されているなど、いくつかの点で標準から逸脱したデータが受け入れられます。

    厳密な構文と緩慢な構文については、「厳密なJSON構文と緩慢なJSON構文」を参照してください。

  • 厳密または緩慢な型互換性。これは、JSON値をそれらのJSON言語型に関して厳密に比較するかどうかに言及しています。

    厳密な型互換性では、値が、想定している型と同じJSON言語型ファミリである必要があります。たとえば、想定している型がnumberである場合、互換性のある値は、数値である必要があります。緩慢な型互換性では、値を、想定している型に変換しようとします。たとえば、文字列"42"は、型numberと緩慢な互換性があります。

    厳密な型互換性と緩慢な型互換性については、「SQLファンクションおよび条件のTYPE句」を参照してください。

関連項目: