Hier is een waanzinnig ingewikkelde manier om dit te doen in MySQL, met behulp van JSON_TABLE
om de update en originele JSON-waarden om te zetten in kolommen, waarbij de kolommen worden samengevoegd met behulp van een (gesimuleerde) FULL JOIN
en vervolgens de output-JSON-waarde opnieuw te maken met JSON_OBJECT
en JSON_ARRAYAGG
; eindelijk gebruiken om de originele tabel bij te werken:
WITH upd AS (
SELECT *
FROM JSON_TABLE('[{"substanceId": 182, "text": "substance_name_182_new"}, {"substanceId": 184, "text": "substance_name_184"}]',
'$[*]' COLUMNS (
substanceId INT PATH '$.substanceId',
txt VARCHAR (100) PATH '$.text')
) jt
CROSS JOIN (SELECT DISTINCT id
FROM test) t
),
cur AS (
SELECT id, substanceId, txt
FROM test
JOIN JSON_TABLE(test.j,
'$[*]' COLUMNS (
substanceId INT PATH '$.substanceId',
txt VARCHAR (100) PATH '$.text')
) jt
),
allv AS (
SELECT COALESCE(upd.id, cur.id) AS id,
COALESCE(upd.substanceId, cur.substanceId) AS substanceId,
COALESCE(upd.txt, cur.txt) AS txt
FROM upd
LEFT JOIN cur ON cur.substanceId = upd.substanceId
UNION ALL
SELECT COALESCE(upd.id, cur.id) AS id,
COALESCE(upd.substanceId, cur.substanceId) AS substanceId,
COALESCE(upd.txt, cur.txt) AS txt
FROM upd
RIGHT JOIN cur ON cur.substanceId = upd.substanceId
),
obj AS (
SELECT DISTINCT id, JSON_OBJECT('substanceId', substanceId, 'text', txt) AS o
FROM allv
),
arr AS (
SELECT id, JSON_ARRAYAGG(o) AS a
FROM obj
GROUP BY id
)
UPDATE test
JOIN arr ON test.id = arr.id
SET test.j = arr.a
;
SELECT JSON_PRETTY(j)
FROM test
Uitgang:
[
{
"text": "substance_name_183",
"substanceId": 183
},
{
"text": "substance_name_184",
"substanceId": 184
},
{
"text": "substance_name_182_new",
"substanceId": 182
}
]
Let op:hierbij wordt ervan uitgegaan dat u een unieke id
gebruikt waarde om de rijen in uw tabel te onderscheiden. Als je iets anders gebruikt, moet je dat omwisselen waar id
wordt gebruikt in de bovenstaande zoekopdracht.