MySQL バージョン 5.7.13 の時点で、
{"test1": "Test 1", "test2": {"test3": "Test 3"}}
あなたの例attributes
では、更新されている列はに設定されています{"test1": "Test 1"}
最初のUPDATE
クエリを見ると、$.test2.test3
存在しないことがわかります。したがって、次のように設定することはできません
JSON_SET() JSON ドキュメントのデータを挿入または更新し、結果を返します。いずれかの引数が NULL の場合、または path が指定されている場合、オブジェクトが見つからない場合は NULL を返します。
つまり、MySQL は を追加できます$.test2
が、$.test2
はオブジェクトではないため、MySQL は に追加できません$.test2.test3
。
$.test2
したがって、次のようにして json オブジェクトとして定義する必要があります。
mysql> SELECT * FROM testing;
+----+---------------------+
| id | attributes |
+----+---------------------+
| 1 | {"test1": "Test 1"} |
+----+---------------------+
1 row in set (0.00 sec)
mysql> UPDATE testing
-> SET attributes = JSON_SET(
-> attributes,
-> "$.test1", "Test 1",
-> "$.test2", JSON_OBJECT("test3", "Test 3")
-> );
Query OK, 1 row affected (0.03 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> SELECT * FROM testing;
+----+---------------------------------------------------+
| id | attributes |
+----+---------------------------------------------------+
| 1 | {"test1": "Test 1", "test2": {"test3": "Test 3"}} |
+----+---------------------------------------------------+
1 row in set (0.00 sec)
そのため、MySQL のドット表記に頼る代わりに、キーが JSON オブジェクトとして存在することを MySQL に明示的に伝える必要があります。
これは、PHP が存在しないオブジェクトのプロパティ値を定義する方法と似ています。
$a = (object) ['test1' => 'Test 1'];
$a->test2->test3 = 'Test 3';
//PHP Warning: Creating default object from empty value
エラーを取り除くには、まず$a->test2
オブジェクトとして定義する必要があります。
$a = (object) ['test1' => 'Test 1'];
$a->test2 = (object) ['test3' => 'Test 3'];
または、ドット表記を使用して値を設定する前に、オブジェクトをテストして作成することもできます。大規模なデータセットでは、これは望ましくない場合があります。
mysql> UPDATE testing
-> SET attributes = JSON_SET(
-> attributes, "$.test2", IFNULL(attributes->'$.test2', JSON_OBJECT())
-> ),
-> attributes = JSON_SET(
-> attributes, "$.test4", IFNULL(attributes->'$.test4', JSON_OBJECT())
-> ),
-> attributes = JSON_SET(
-> attributes, "$.test4.test5", IFNULL(attributes->'$.test4.test5', JSON_OBJECT())
-> ),
-> attributes = JSON_SET(
-> attributes, "$.test2.test3", "Test 3"
-> );
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> SELECT * FROM testing;
+----+---------------------------------------------------------------------------+
| id | attributes |
+----+---------------------------------------------------------------------------+
| 1 | {"test1": "Test 1", "test2": {"test3": "Test 3"}, "test4": {"test5": {}}} |
+----+---------------------------------------------------------------------------+
1 row in set (0.00 sec)
どちらの場合でも、元のデータが提供されていない場合、JSON_OBJECT 関数呼び出しは、ネストされたオブジェクトのプロパティ値を空にします。JSON_SET
しかし、最後のクエリからわかるよう$.test1
に、 は の定義で提供されておらずattributes
、そのまま残っていたため、変更されていないプロパティはクエリから省略できます。