2023年7月23日日曜日

SQLite3 JSONの要素を削除する(json_remove())

概要

SQLiteでJSONオブジェクトの要素を削除するには json_removeを使用する。

構文


json_remove(JSON_OBJECT, JSON_PATH, JSON_PATH ...)
                
JSON_OBJECT
対象のJSON文字列、もしくはJSONオブジェクト
JSON_PATH
削除する要素のJSON Path。複数指定可能。

実行例

環境
  • Windows 10 64bit
  • SQLite3 (3.41.2) Command-Line Shell
基本的な使い方

sqlite> .log stderr
sqlite> .nullvalue [null]

sqlite> -- # 1.
sqlite> select json_remove('[0,1,2,3,4]', '$[0]');
[1,2,3,4]
sqlite> select json_remove('[0,1,2,3,4]', '$[#-1]');
[0,1,2,3]
sqlite> select json_remove('{"a":10, "b":20}', '$.a');
{"b":20}

sqlite> -- # 2.
sqlite> select json_remove('{"a":10, "b":[0, 1, 2]}', '$.b');
{"a":10}

sqlite> -- # 3.
sqlite> select json_remove('[0,1,2,3,4]', '$');
[null]

sqlite> -- # 4.
sqlite> select json_remove('[1]', '$[0]');
[]
sqlite> select json_remove('{"a":10}', '$.a');
{}

sqlite> -- # 5.
sqlite> select json_remove('[0,1,2,3,4]', '$[10]');
[0,1,2,3,4]
sqlite> select json_remove('[0,1,2,3,4]', '$[#]');
[0,1,2,3,4]
sqlite> select json_remove('{"a":10, "b":20}', '$.z');
{"a":10,"b":20}
                    
  1. JSON Pathで位置を指定して要素を削除する
  2. 指定したJSON Path以下のパスの要素も削除される
  3. ルート要素を削除するとNULLが返る
  4. 配列やオブジェクト内の要素を全部削除すると、空の配列やオブジェクトが残る
  5. 存在しないJSON Pathを指定しても何も起こらずエラーも出力されない
引数に複数のJSON Pathを指定した場合

json_remove()の第2引数以降にJSON Pathを複数指定できる。 ただし、第2引数で指定された要素を削除された後のJSONデータに対し、 第3引数で指定されたJSON Pathが評価される、という順番のようなので 特に配列内の要素を順番を指定して削除する場合には注意すること。


sqlite> -- # 1.
sqlite> select json_remove('{"a":10, "b":20, "c":30, "d":40}', '$.a', '$.c');
{"b":20,"d":40}
sqlite> select json_remove('{"a":10, "b":20, "c":30, "d":40}', '$.a', '$.c', '$.d');
{"b":20}

sqlite> -- # 2.
sqlite> select json_remove('[0,1,2,3,4]', '$[0]', '$[2]');
[1,2,4]
sqlite> select json_remove('[0,1,2,3,4]', '$[0]', '$[1]');
[1,3,4]
sqlite> select json_remove('[0,1,2,3,4]', '$[0]', '$[0]', '$[0]');
[3,4]

sqlite> -- # 3.
sqlite> select json_remove('[0,1,2,3,4]', '$[0]', '$[0]');
[2,3,4]
sqlite> select json_remove(
   ...>             json_remove('[0,1,2,3,4]', '$[0]')
   ...>             , '$[0]'
   ...>         );
[2,3,4]
                    
  1. 複数のJSON Pathを指定して要素を削除出来る
  2. 配列の順番を指定する場合は順番に注意する必要がある
  3. この二つのSQLは同じ結果を返す
第1引数にJSONオブジェクト以外を指定した場合

テキスト型を指定した場合のみエラーになる模様。 他の型は「$」をJSON Pathに指定すれば削除される。


sqlite> .nullvalue [null]

sqlite> -- # 1.
sqlite> select json_remove(1, '$[0]');
1
sqlite> select json_remove('test', '$[0]');
Runtime error: malformed JSON
sqlite> select json_remove(true, '$[0]');
1
sqlite> select json_remove(false, '$[0]');
0

sqlite> -- # 2.
sqlite> select json_remove(1, '$');
[null]
sqlite> select json_remove('test', '$');
Runtime error: malformed JSON
sqlite> select json_remove(true, '$');
[null]
sqlite> select json_remove(false, '$');
[null]
                    
  1. テキストを指定した場合のみJSONエラーになる
  2. 「$」を指定すれば削除されてNULLが返る
引数を一つしか指定しなかった場合

第1引数がJSONとして認識されればエラーにならない


sqlite> .log strerr

sqlite> select json_remove(1);
1
sqlite> select json_remove('[0,1,2,3,4]');
[0,1,2,3,4]
sqlite> select json_remove(true);
1
sqlite> select json_remove(false);
0
sqlite> select json_remove('test');
Runtime error: malformed JSON
sqlite> select json_remove('$');
Runtime error: malformed JSON
                    

参考URL