Angenommen, Sie wollen ein Endergebnis von
{"test1": "Test 1", "test2": {"test3": "Test 3"}}
In Ihrem Beispiel die attributes
Spalte, die aktualisiert wird wird auf {"test1": "Test 1"}
Ein Blick auf Ihre anfänglichen UPDATE
Abfrage, können wir sehen $.test2.test3
nicht existiert . So kann es nicht als JSON_SET() Inserts or updates data in a JSON document and returns the result. Returns NULL if any argument is NULL or path, if given, does not locate an object.
MySQL gesetzt Bedeutung $.test2
hinzufügen können, aber da $.test2
kein Objekt ist, MySQL kann $.test2.test3
nicht erneut auf.
Sie müssten also $.test2
als JSON-Objekt definieren, indem Sie Folgendes tun.
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)
Anstatt also auf der MySQL-Punktnotation zu verlassen, würden Sie ausdrücklich MySQL muss sagen, dass der Schlüssel als JSON-Objekt vorhanden ist.
Dies ähnelt der Definition von nicht vorhandenen Objekteigenschaftswerten durch PHP.
$a = (object) ['test1' => 'Test 1'];
$a->test2->test3 = 'Test 3';
//PHP Warning: Creating default object from empty value
Um die Fehler loszuwerden, würden Sie zuerst $a->test2
als Objekt definieren müssen.
Alternativ können Sie die Objekte testen und erstellen, bevor Sie die Punktnotation verwenden, um die Werte festzulegen. Bei größeren Datensätzen kann dies jedoch unerwünscht sein.
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)
Obwohl in jedem Fall, wenn die ursprünglichen Daten nicht den JSON_OBJECT Funktionsaufruf zur Verfügung gestellt werden, wird das verschachtelte Objekt des Eigenschaftswert leer aus (s). Aber wie Sie aus der letzten JSON_SET
Abfrage sehen können, $.test1
wurde nicht in der Definition von attributes
zur Verfügung gestellt, und es blieb intakt, so dass diese Eigenschaften, die nicht geändert werden, aus der Abfrage weggelassen werden können.
Das ist echte Schmerzen IMO. Ich habe eine Feature-Anforderung http://bugs.mysql.com/bug.php?id=84167 eingereicht. Vielleicht, wenn Sie Minute haben, können Sie es unterstützen, indem Sie auf die Schaltfläche Effekte mich klicken:) Oder kommentieren. –