Voici une manière incroyablement compliquée de le faire dans MySQL, en utilisant JSON_TABLE
pour convertir les valeurs JSON de mise à jour et d'origine en colonnes, en fusionnant les colonnes à l'aide d'un FULL JOIN
(simulé) puis en recréant la valeur JSON de sortie en utilisant JSON_OBJECT
et JSON_ARRAYAGG
; finalement l'utiliser pour mettre à jour la table d'origine :
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
Sortie :
[
{
"text": "substance_name_183",
"substanceId": 183
},
{
"text": "substance_name_184",
"substanceId": 184
},
{
"text": "substance_name_182_new",
"substanceId": 182
}
]
Notez que cela suppose que vous utilisez un id
unique valeur pour distinguer les lignes de votre tableau. Si vous utilisez autre chose, vous devrez l'échanger dans où id
est utilisé dans la requête ci-dessus.