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

MySQL 8修改JSON数组指定元素值失败,请求排查代码错误

问题分析:修改JSON数组中指定条件元素的字段失败

问题背景

现有JSON结构如下:

{"details": {
  "product_name": "Example Product",
  "description": "This is an example product",
  "price": 10.99,
  "dimensions": {
    "width": 10,
    "height": 15,
    "depth": 5
  },
  "reviews": [
    {
      "author": "John Smith",
      "rating": 4,
      "comment": "Great product, would buy again"
    },
    {
      "author": "Jane Doe",
      "rating": 3,
      "comment": "Product was okay, not great"
    }
  ]
 }}

需求:修改reviews数组中rating等于3的元素的author字段值。

尝试的SQL语句

UPDATE my_table SET json_data = JSON_REPLACE(json_data, 
    JSON_UNQUOTE(
        REPLACE(
            JSON_SEARCH(json_data, 'one', 3, NULL, '$.details.reviews[*].rating'), 
            '.rating', '.author'
        )
    ),
    'New Author'
)
WHERE JSON_SEARCH(json_data, 'one', 3, NULL, '$.details.reviews[*].rating') IS NOT NULL;

错误原因

核心问题是JSON_SEARCH默认只匹配字符串类型的值,而你的rating是数值类型的3,JSON_SEARCH会在JSON里找字符串"3"而非数值3,所以根本找不到对应的路径,WHERE条件不成立,自然不会执行任何更新。

即使你把搜索值改成字符串"3",因为JSON里的rating是数值类型,类型不匹配依然匹配不到。

正确解决方案

方法一:用JSON_CONTAINS匹配数值,构造路径更新(MySQL 5.7+支持)

UPDATE my_table 
SET json_data = JSON_REPLACE(
    json_data,
    REPLACE(
        JSON_UNQUOTE(JSON_SEARCH(json_data, 'one', CAST(3 AS CHAR), NULL, '$.details.reviews[*].rating')),
        '.rating',
        '.author'
    ),
    'New Author'
)
WHERE JSON_CONTAINS(json_data, '3', '$.details.reviews[*].rating');

这里用JSON_CONTAINS匹配数值3(第二个参数传JSON格式的数值字符串'3'),同时用CAST(3 AS CHAR)让JSON_SEARCH能匹配到对应路径。

方法二:用JSON_TABLE拆分数组处理(MySQL 8.0+推荐)

这种方法逻辑更清晰,适合复杂JSON数组操作:

UPDATE my_table t
JOIN (
    SELECT 
        id,
        JSON_UNQUOTE(JSON_SEARCH(t.json_data, 'one', 3, NULL, CONCAT('$.details.reviews[', idx, '].rating'))) AS rating_path
    FROM my_table t,
         JSON_TABLE(
             t.json_data,
             '$.details.reviews[*]' COLUMNS (
                 idx FOR ORDINALITY,
                 rating INT PATH '$.rating'
             )
         ) j
    WHERE j.rating = 3
) j ON t.id = j.id
SET t.json_data = JSON_REPLACE(
    t.json_data,
    REPLACE(j.rating_path, '.rating', '.author'),
    'New Author'
);

通过JSON_TABLE把reviews数组拆成关系表,找到rating=3的元素索引,再构造对应路径更新,彻底避免类型匹配问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 22:07:46