sql >> データベース >  >> RDS >> Sqlserver

SQL ServerのJSON_QUERY()とJSON_VALUE():違いは何ですか?

    SQLServerで使用できる多くのT-SQL関数のうちの2つはJSON_QUERY()です。 およびJSON_VALUE() 。これらの関数を使用して、JSONドキュメントからデータを抽出できます。

    それらの一般的な構文は似ており、一見するとまったく同じことをしていると思うかもしれませんが、そうではありません。 JSONとSQLServerを使用する場合は、両方の機能を使用できる場所が間違いなくあります。

    この記事では、JSON_QUERY()の違いについて説明します。 およびJSON_VALUE()

    違い

    これらの2つの関数の定義はわずかに異なり、構文もわずかに異なり、戻り値もわずかに異なります。

    定義

    2つの関数の定義方法は次のとおりです。

    JSON_QUERY()
    JSON文字列からオブジェクトまたは配列を抽出します。
    JSON_VALUE()
    JSON文字列からスカラー値を抽出します。

    したがって、これら2つの関数の違いは、それらが抽出するものです。 1つはオブジェクトまたは配列を抽出し、もう1つはスカラー値を抽出します。

    構文の違い

    もう1つの違いは、構文にあります:

    JSON_QUERY ( expression [ , path ] )
    JSON_VALUE ( expression , path )
    

    JSON_QUERY()を見てください 構文。 pathを囲む角かっこ 引数は、それがオプションの引数であることを意味します。これは、この関数が必要に応じてJSONドキュメント全体を返すことができるためです。

    ただし、JSON_VALUE()を使用する場合は、path引数が必須の引数です。 働き。したがって、この関数を使用するときは、両方の引数を指定する必要があります。

    戻り値

    そしてもう1つの違いは、戻り値にあります。

    • JSON_QUERY() タイプnvarchar(max)のJSONフラグメントを返します
    • JSON_VALUE() タイプnvarchar(4000)の単一のテキスト値を返します

    例1-スカラー値を抽出する

    スカラー値を抽出しようとするときのこれらの関数の違いを示す例を次に示します。

    SELECT 
      JSON_VALUE('{"Name": "Homer"}', '$.Name') AS 'JSON_VALUE',
      JSON_QUERY('{"Name": "Homer"}', '$.Name') AS 'JSON_QUERY';
    

    結果:

    +--------------+--------------+
    | JSON_VALUE   | JSON_QUERY   |
    |--------------+--------------|
    | Homer        | NULL         |
    +--------------+--------------+
    

    したがって、両方の関数がJSONドキュメントから同じ値を抽出しようとしますが、成功するのは1つだけです:JSON_VALUE() 。これは、抽出しようとしている値がスカラー値であるためです。基本的に、スカラー値 データの1つの単位です。テキストの文字列または数字の場合があります。ただし、オブジェクトや配列にすることはできません。

    例2–配列を抽出する

    この例では、両方の関数が配列全体を抽出しようとします。

    DECLARE @data NVARCHAR(4000)
    SET @data=N'{  
        "Suspect": {    
           "Name": "Homer Simpson",
           "Hobbies": ["Eating", "Sleeping", "Base Jumping"]  
        }
     }'
     SELECT 
       JSON_VALUE(@data,'$.Suspect.Hobbies') AS 'JSON_VALUE',
       JSON_QUERY(@data,'$.Suspect.Hobbies') AS 'JSON_QUERY';
    

    結果:

    +--------------+----------------------------------------+
    | JSON_VALUE   | JSON_QUERY                             |
    |--------------+----------------------------------------|
    | NULL         | ["Eating", "Sleeping", "Base Jumping"] |
    +--------------+----------------------------------------+
    

    この場合、JSON_QUERY()のみ 関数は成功します。

    例3–配列アイテムを抽出する

    この例は前の例と似ていますが、配列全体を抽出しようとするのではなく、配列から1つのアイテムのみが必要な点が異なります。

    DECLARE @data NVARCHAR(4000)
    SET @data=N'{  
        "Suspect": {    
           "Name": "Homer Simpson",
           "Hobbies": ["Eating", "Sleeping", "Base Jumping"]  
        }
     }'
     SELECT 
       JSON_VALUE(@data,'$.Suspect.Hobbies[2]') AS 'JSON_VALUE',
       JSON_QUERY(@data,'$.Suspect.Hobbies[2]') AS 'JSON_QUERY';
    

    結果:

    +--------------+--------------+
    | JSON_VALUE   | JSON_QUERY   |
    |--------------+--------------|
    | Base Jumping | NULL         |
    +--------------+--------------+
    

    したがって、今回はJSON_VALUE() 勝者です。

    例4–オブジェクトを抽出する

    オブジェクト全体を試してみましょう。

    DECLARE @data NVARCHAR(4000)
    SET @data=N'{  
        "Suspect": {    
           "Name": "Homer Simpson",
           "Hobbies": ["Eating", "Sleeping", "Base Jumping"]  
        }
     }'
     SELECT 
       JSON_VALUE(@data,'$.Suspect') AS 'JSON_VALUE',
       JSON_QUERY(@data,'$.Suspect') AS 'JSON_QUERY';
    

    結果:

    +--------------+--------------+
    | JSON_VALUE   | JSON_QUERY   |
    |--------------+--------------|
    | NULL         | {    
           "Name": "Homer Simpson",
           "Hobbies": ["Eating", "Sleeping", "Base Jumping"]  
        }              |
    +--------------+--------------+
    

    そしてJSON_QUERY() 勝ちます。

    (フォーマットを失礼します。これが私のMSSQLコマンドラインツールが結果を返す方法です。)

    例5–JSONドキュメント全体を抽出する

    JSONドキュメント全体を試してみましょう。

    DECLARE @data NVARCHAR(4000)
    SET @data=N'{
        "Cities": [
            {
                "Name": "Kabul",
                "CountryCode": "AFG",
                "District": "Kabol",
                "Population": 1780000
            },
            {
                "Name": "Qandahar",
                "CountryCode": "AFG",
                "District": "Qandahar",
                "Population": 237500
            }
        ]
    }'
    SELECT 
      JSON_VALUE(@data, '$') AS 'JSON_VALUE', 
      JSON_QUERY(@data, '$') AS 'JSON_QUERY';
    

    結果:

    +--------------+--------------+
    | JSON_VALUE   | JSON_QUERY   |
    |--------------+--------------|
    | NULL         | {
        "Cities": [
            {
                "Name": "Kabul",
                "CountryCode": "AFG",
                "District": "Kabol",
                "Population": 1780000
            },
            {
                "Name": "Qandahar",
                "CountryCode": "AFG",
                "District": "Qandahar",
                "Population": 237500
            }
        ]
    }              |
    +--------------+--------------+
    

    したがって、JSON_QUERY() ドキュメント全体を返すことができるのは1つだけです。

    例6–パスを省略

    これら2つの関数のもう1つの違いは、JSON_QUERY()を使用する場合、path引数はオプションであるということです。 。これを省略すると、JSONドキュメント全体が返されます。

    JSON_VALUE()を使用する場合は、この引数を省略できません。 、必須の引数であるため。これはおそらく、関数がスカラー値しか返すことができないという事実によるものです。最初の引数がスカラー値のみで構成されている場合、それは有効なJSONではありません。

    とにかく、JSON_QUERY()からpath引数を省略した例を次に示します。 :

    SELECT JSON_QUERY('{"Name": "Homer"}') AS 'Result';
    

    結果:

    +-------------------+
    | Result            |
    |-------------------|
    | {"Name": "Homer"} |
    +-------------------+
    

    そして、JSON_VALUE()でそのトリックを試してみるとどうなりますか。 :

    SELECT JSON_VALUE('{"Name": "Homer"}') AS 'Result';
    

    結果:

    Msg 174, Level 15, State 1, Line 1
    The json_value function requires 2 argument(s).
    

    例7–パスモード

    前の例では、関数が指定されたパスを処理できなかった場合、NULLを返しました。 。これは、これらの例がすべて緩いモード(デフォルトモード)で実行されたためです。

    厳密モードで実行すると、代わりにエラーが発生します。パスモードを明示的に指定するには、ドル記号の前にパスモードを追加します(そしてそれらの間にスペースを残します)。

    厳密モードで無効なパスを指定するとどうなるかの例を次に示します。

    SELECT 
      JSON_VALUE('{"Name": "Homer"}', 'strict $.Name') AS 'JSON_VALUE',
      JSON_QUERY('{"Name": "Homer"}', 'strict $.Name') AS 'JSON_QUERY';
    

    結果:

    Msg 13624, Level 16, State 2, Line 1
    Object or array cannot be found in the specified JSON path.
    

    1. 日付スタンプを使用してテーブルを作成する

    2. MariaDBでのSUBSTRING_INDEX()のしくみ

    3. エラー:INSERTEXECステートメントをネストできません。およびINSERT-EXECステートメント内でROLLBACKステートメントを使用することはできません。これを解決する方法は?

    4. データベースセキュリティのためのPercona監査ログプラグインの使用