按给定键更新 JSON 数据类型列中的值

Update Values in JSON Data Type Column by given key

我的网站使用 mysql。不幸的是,由于以前的开发人员,数据库设计很糟糕,对其进行更改需要很多时间。

我想解释一下我想做什么。我有 table 名为 content.

id content category_id
1 { "content_de": "some german content", "content_en": ""} 150
2 { "content_de": "some german content 2", "content_en": ""} 150

因此,如您所见,content_en 键在内容列的 json 中是空的。我想将 content_de 键的值复制到 content_en 键的值中,其中 category_id 是 150.

查询后的结果应该是这样的

id content category_id
1 { "content_de": "some german content", "content_en": "some german content"} 150
2 { "content_de": "some german content 2", "content_en": "some german content 2"} 150

我怎样才能完成这个任务?

您可以通过使用 JSON_SET() 函数对 JSON 值进行部分更新,例如

UPDATE person p
   SET content = JSON_SET(
                          content, 
                          '$.content_en', 
                          JSON_EXTRACT(content, '$.content_de')
                         )
 WHERE category_id = 150   

Demo

上面的也适用于数据库的版本 5.7,但是如果您的数据库的当前版本是 8.0+,那么下面的选项可能是另一个使用选项

UPDATE person p
  JOIN JSON_TABLE(
                 p.content,
                '$.content_de' COLUMNS (extracted_content VARCHAR(800) PATH '$')
       ) j
   SET content = JSON_SET(content, '$.content_en', extracted_content)
 WHERE category_id = 150 

我找到了解决办法。我不得不使用存储过程迭代地更新行中键的值。

内容行的 json 数据中也有很多键(不仅 content_de)。所以我只是在 while 循环中为每个键一个一个地创建和声明查询。

其实一开始我试过用通配符来申请不这样的

可能是这样; “找到以 _de 结尾的键,然后用以 _en 结尾的键的值替换它们的值”。但后来我意识到这需要另一种控制机制,比如匹配相同的键等。

我刚刚用这个查询解决了我的问题。

DROP PROCEDURE IF EXISTS updateJSONData;
DELIMITER //
CREATE PROCEDURE updateJSONData()
BEGIN

DECLARE n INT DEFAULT 0;
DECLARE i INT DEFAULT 0;

SET @menuID = 151;
SET i = 0;

select COUNT(id) from sayfa_icerik where menuID = @menuID and durum = 1 and lang_en = 1 INTO n;

WHILE i < n DO 

    SET @id = (select id from sayfa_icerik where menuID = @menuID and durum = 1 and lang_en = 1 LIMIT i,1);

    set @sertifika = (SELECT json_extract(icerik, '$.sertifika_de') FROM sayfa_icerik WHERE menuId = @menuID and id = @id);

    update sayfa_icerik set icerik = json_replace(icerik, '$.sertifika_en', JSON_UNQUOTE(@sertifika)) where menuId = @menuID and id = @id;

    ...


    set @video = (SELECT json_extract(icerik, '$.video_de') FROM sayfa_icerik WHERE menuId = @menuID and id = @id);

    update sayfa_icerik set icerik = json_replace(icerik, '$.video_en', JSON_UNQUOTE(@video)) where menuId = @menuID and id = @id;

 
   ...

  SET i = i + 1;

END WHILE;

END //
call updateJSONData;

注:OP 在问题部分提供的答案。