You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MySQL中更新JSON数组对象内的languageCode值

需求与现有实现

我有一张applications表,其中Description列存储JSON数组格式的数据,示例记录如下:

[
    {"languageCode":"fr","description":"France","isDefault":true},
    {"languageCode":"cs","description":"Czech","isDefault":false},
    {"languageCode":"it-IT","description":"Italian","isDefault":false}
]

和

[
    {"languageCode":"cs","description":"Czech","isDefault":false},
    {"languageCode":"it-IT","description":"Italian","isDefault":false},
    {"languageCode":"fr-FR","description":"France","isDefault":true}
]

需要将所有记录中languageCode为"fr"的修改为"fr-FR","cs"修改为"cs-CZ",期望结果如下:

[
    {"languageCode":"fr-FR","description":"France","isDefault":true},
    {"languageCode":"cs-CZ","description":"Czech","isDefault":false},
    {"languageCode":"it-IT","description":"Italian","isDefault":false}
]

和

[
    {"languageCode":"cs-CZ","description":"Czech","isDefault":false},
    {"languageCode":"it-IT","description":"Italian","isDefault":false},
    {"languageCode":"fr-FR","description":"France","isDefault":true}
]

我已经通过嵌套REPLACE语句实现了需求:

UPDATE applications
SET Description = REPLACE ( REPLACE ( Description, '"languageCode":"fr"', '"languageCode":"fr-FR"'), '"languageCode":"cs"', '"languageCode":"cs-CZ"')

但希望使用更规范的JSON相关方法来完成这个更新操作。


基于JSON函数的优化方案

字符串REPLACE虽然简单,但存在误替换风险(比如description字段中恰好包含匹配文本的情况)。以下是针对主流数据库的安全JSON处理方案:

SQL Server

使用OPENJSON拆分JSON数组,修改字段后再用FOR JSON PATH重组:

UPDATE a
SET Description = (
    SELECT 
        CASE 
            WHEN j.languageCode = 'fr' THEN 'fr-FR'
            WHEN j.languageCode = 'cs' THEN 'cs-CZ'
            ELSE j.languageCode
        END AS languageCode,
        j.description,
        j.isDefault
    FROM OPENJSON(a.Description)
    WITH (
        languageCode NVARCHAR(10),
        description NVARCHAR(100),
        isDefault BIT
    ) j
    FOR JSON PATH
)
FROM applications a

MySQL

借助JSON_TABLE解析数组,JSON_OBJECT重建对象,JSON_ARRAYAGG聚合为数组:

UPDATE applications a
JOIN (
    SELECT 
        id, -- 替换为你的表主键字段
        JSON_ARRAYAGG(
            JSON_OBJECT(
                'languageCode', CASE WHEN j.languageCode = 'fr' THEN 'fr-FR' WHEN j.languageCode = 'cs' THEN 'cs-CZ' ELSE j.languageCode END,
                'description', j.description,
                'isDefault', j.isDefault
            )
        ) AS new_description
    FROM applications,
         JSON_TABLE(
             Description,
             '$[*]' COLUMNS (
                 languageCode VARCHAR(10) PATH '$.languageCode',
                 description VARCHAR(100) PATH '$.description',
                 isDefault BOOLEAN PATH '$.isDefault'
             )
         ) j
    GROUP BY id
) b ON a.id = b.id
SET a.Description = b.new_description;

PostgreSQL

利用jsonb_array_elements拆分数组,jsonb_build_object重建对象,jsonb_agg聚合回数组:

UPDATE applications a
SET Description = (
    SELECT jsonb_agg(
        jsonb_build_object(
            'languageCode', CASE WHEN j.language_code = 'fr' THEN 'fr-FR' WHEN j.language_code = 'cs' THEN 'cs-CZ' ELSE j.language_code END,
            'description', j.description,
            'isDefault', j.is_default
        )
    )
    FROM jsonb_array_elements(a.Description::jsonb) j,
         jsonb_to_record(j) AS x(language_code text, description text, is_default boolean)
)::json; -- 如果原字段是json类型,需要转换回来

方案对比
  • 字符串REPLACE:实现成本低,但容错性差,易出现误替换
  • JSON函数方案:严格针对JSON结构中的指定字段修改,避免误操作,适合复杂JSON场景,扩展性更强

内容的提问来源于stack exchange,提问作者Babatos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 08:01:58