按给定键更新 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
上面的也适用于数据库的版本 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 在问题部分提供的答案。
我的网站使用 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
上面的也适用于数据库的版本 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 在问题部分提供的答案。