Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Partial update of JSON Object in MySQL

Good afternoon,

When I try to update part of a JSON Object, using ON DUPLICATE KEY UPDATE, how do you update a specific value with a key?

The code executes successfully but all values are updated when I just want the stock to change on update.

Any help would be welcomed, I am not convinced, I understand the MySQL JSON Path syntax, or perhaps JSON_SET cannot achieve my goal?

INSERT INTO table (name, attributes) VALUES
("Sarah", JSON_OBJECT('profile', "F", "el", "[4, 5, 6]")),
("John",  JSON_OBJECT('profile', "M", "el", "[10]"))
AS t
ON DUPLICATE KEY UPDATE
  attributes = JSON_SET(t.attributes, '$.attributes.el',  '$.attributes.el')
                                                         # ^
                                                         # +--- value being inserted

I have also tried another flavour without success:

attributes = JSON_REPLACE(t.attributes, '$.t.el', "$.t.el")

Third attempt using wildcards and json extract, which replaces the entire JSON_OBJECT()

attributes = JSON_REPLACE(t.attributes, '$.t[2]', JSON_EXTRACT(t.attributes, "$.stock"))
like image 380
dimButTries Avatar asked Nov 23 '21 15:11

dimButTries


People also ask

How do you update a specific object in a JSON array in MySQL?

JSON_SET() – Insert or Update Values in a JSON Document in MySQL. In MySQL, the JSON_SET() function inserts or updates values in a JSON document and returns the result. You provide the JSON document as the first argument, followed by the path to insert into, followed by the value to insert.

What is the drawback of JSON columns in MySQL?

The drawback? If your JSON has multiple fields with the same key, only one of them, the last one, will be retained. The other drawback is that MySQL doesn't support indexing JSON columns, which means that searching through your JSON documents could result in a full table scan.

Can we update JSON?

You can use json_mergepatch in an UPDATE statement, to update the documents in a JSON column.

Can we store JSON object in MySQL?

MySQL supports a native JSON data type defined by RFC 7159 that enables efficient access to data in JSON (JavaScript Object Notation) documents. The JSON data type provides these advantages over storing JSON-format strings in a string column: Automatic validation of JSON documents stored in JSON columns.


1 Answers

If I understand correctly, you just need to use the VALUES function inside INSERT ... ON DUPLICATE KEY UPDATE statement which gives you access to the value being inserted:

CREATE TABLE t(
  name varchar(100) NOT NULL UNIQUE,
  attributes JSON
);

INSERT INTO t(name, attributes) VALUES
('Sarah', '{"profile": "F", "el": ["insrted", 1]}'),
('John',  '{"profile": "M", "el": ["insrted", 2]}');

-- insert + on duplicate (mysql 5.x)
INSERT INTO t(name, attributes) VALUES
('Sarah', '{"profile": "F", "el": ["dup_upd", 3]}'),
('John',  '{"profile": "M", "el": ["dup_upd", 4]}'),
('Jack',  '{"profile": "M", "el": ["insrted", 1]}')
ON DUPLICATE KEY UPDATE attributes =
    JSON_SET(attributes, '$.el', JSON_EXTRACT(VALUES(attributes), '$.el'));

-- insert + on duplicate (mysql 8.x)
INSERT INTO t(name, attributes) VALUES
('Sarah', '{"profile": "F", "el": ["dup_upd", 3]}'),
('John',  '{"profile": "M", "el": ["dup_upd", 4]}'),
('Jack',  '{"profile": "M", "el": ["insrted", 1]}')
AS t_ins
ON DUPLICATE KEY UPDATE attributes =
    JSON_SET(t.attributes, '$.el', JSON_EXTRACT(t_ins.attributes, '$.el'));

SELECT name, JSON_PRETTY(attributes)
FROM t
name  | JSON_PRETTY(attributes)
------|-------------------------------------------
Sarah | {"el": ["dup_upd", 3], "profile": "F"}
John  | {"el": ["dup_upd", 4], "profile": "M"}
Jack  | {"el": ["insrted", 1], "profile": "M"}

Demo on DB<>Fiddle

like image 51
Salman A Avatar answered Sep 24 '22 15:09

Salman A