当前位置:首页 > 文章列表 > 数据库 > MySQL > MySQL JSON_VALUE 怎样区分路径不存在和 JSON 空值

MySQL JSON_VALUE 怎样区分路径不存在和 JSON 空值

来源:17golang原创 2026-10-20 22:13:23 0浏览 收藏

在 MySQL JSON 查询里,路径不存在和 JSON 文档里的 null 很容易都落成 SQL NULL,后续业务就无法判断“字段没传”还是“字段明确为空”。解决办法是先把三种输入放在同一组基线里,再分别利用 ON EMPTY、ON ERROR 和 JSON_CONTAINS_PATH() 拆开判断。

官方文档:https://dev.mysql.com/doc/refman/8.4/en/json-search-functions.html

路径不存在由 ON EMPTY 处理,JSON null 会返回 SQL NULL;如果需要稳定区分两者,要么给缺失路径设置独有的默认哨兵值,要么额外判断路径是否存在。类型转换失败则属于 ON ERROR 分支。

先建立三种输入基线

排查这类问题时,我会先固定一个 JSON 文档,只改变被读取的路径。这样观察到的差异来自数据分支,而不是查询写法变化。下面的样例故意同时放入正常字符串、JSON null,并让第三个路径完全不存在。

-- 用同一份文档对照正常值、JSON null 和缺失路径
SET @doc = '{"name":"Lin","nickname":null}';

SELECT
  JSON_VALUE(@doc, '$.name') AS normal_value,
  JSON_VALUE(@doc, '$.nickname') AS json_null_value,
  JSON_VALUE(@doc, '$.missing') AS missing_value;

这组输入可以先整理成三个基线:

输入情况JSON_VALUE 的关注点默认观察结果
$.name 有字符串提取标量并返回默认字符串类型Lin
$.nickname 是 JSON nullJSON null 转成 SQL NULLSQL NULL
$.missing 没有匹配路径触发 ON EMPTY默认也是 SQL NULL

最后两行的结果相同,正是误判的来源。此时不要急着在外层用 IFNULL() 补一个业务值,因为它会把“缺失”和“明确为空”继续合并。

MySQL JSON_VALUE 将路径缺失、JSON null 和正常值分成不同返回分支的静态结构图
图1:JSON_VALUE 三类输入与 ON EMPTY、SQL NULL、正常值之间的静态关系示意图,不是运行截图。

读懂 JSON_VALUE 的默认分支

JSON_VALUE(json_doc, path) 先按路径取值,再把结果转换为标量。没有额外配置时,返回类型是 VARCHAR(512);路径没有数据时默认走 NULL ON EMPTY,转换或取到对象、数组等错误情况默认走 NULL ON ERROR。

两个子句解决的是两类不同问题:

  • ON EMPTY:路径没有找到数据。
  • ON ERROR:路径找到的内容不能按要求转换成目标标量,或者结果不满足标量约束。

写法顺序也有要求,ON EMPTY 必须在 ON ERROR 前面。把顺序写反,容易得到语法错误或兼容性警告。

-- 为缺失路径指定独有哨兵,为转换错误保留 SQL NULL
SELECT
  JSON_VALUE(
    @doc,
    '$.missing'
    RETURNING CHAR(32)
    DEFAULT '__MISSING__' ON EMPTY
    NULL ON ERROR
  ) AS missing_marker,
  JSON_VALUE(
    '{"age":"unknown"}',
    '$.age'
    RETURNING UNSIGNED
    NULL ON EMPTY
    DEFAULT 0 ON ERROR
  ) AS conversion_fallback;

这里的哨兵值只服务于“路径缺失”这个状态,应该选业务数据不可能自然出现的值。对于数值类型,不要把普通的 0 当成万能哨兵,因为 0 可能本来就是合法业务值。

用哨兵值区分路径缺失

如果查询只需要在结果层区分缺失和 JSON null,最短的做法是让 ON EMPTY 返回一个独有字符串,而 JSON null 继续保持 SQL NULL:

-- 缺失路径返回哨兵,JSON null 仍然保持 SQL NULL
SELECT
  CASE
    WHEN JSON_VALUE(
      @doc,
      '$.missing'
      RETURNING CHAR(32)
      DEFAULT '__MISSING__' ON EMPTY
      NULL ON ERROR
    ) = '__MISSING__' THEN 'missing'
    WHEN JSON_VALUE(
      @doc,
      '$.missing'
      RETURNING CHAR(32)
      DEFAULT '__MISSING__' ON EMPTY
      NULL ON ERROR
    ) IS NULL THEN 'json-null-or-error'
    ELSE 'present'
  END AS state;

这段写法适合展示规则,但在真实查询里不建议重复调用同一个表达式。可以先在派生表中得到一次结果,再由外层 CASE 判断,避免后续修改类型或路径时漏改其中一处。

-- 先提取一次,再在外层把哨兵、SQL NULL 和正常值映射成业务状态
SELECT
  CASE
    WHEN value_text = '__MISSING__' THEN 'missing'
    WHEN value_text IS NULL THEN 'json-null'
    ELSE 'present'
  END AS state,
  value_text
FROM (
  SELECT JSON_VALUE(
    @doc,
    '$.nickname'
    RETURNING CHAR(32)
    DEFAULT '__MISSING__' ON EMPTY
    NULL ON ERROR
  ) AS value_text
) AS extracted;

这里有一个容易忽略的边界:如果业务数据本身可能出现 __MISSING__,这个哨兵就不再唯一。此时应该改用更难与业务值冲突的编码约定,或者直接使用下一节的显式路径存在性判断。

用 JSON_CONTAINS_PATH 做显式判定

当字段值允许为空、缺失状态需要长期存储,或查询还要同时保留原始值时,我更倾向于把“路径是否存在”单独算出来。JSON_CONTAINS_PATH() 返回路径是否存在,JSON_VALUE() 负责取标量;两者的职责分开,业务状态更容易解释。

-- 用存在性标记先排除缺失,再用 JSON_VALUE 识别 JSON null
SELECT
  CASE
    WHEN JSON_CONTAINS_PATH(@doc, 'one', '$.missing') = 0 THEN 'missing'
    WHEN JSON_VALUE(@doc, '$.missing') IS NULL THEN 'json-null'
    ELSE 'present'
  END AS state;

-- 对已有路径重复同样的判定,结果会落到 json-null 或 present
SELECT
  CASE
    WHEN JSON_CONTAINS_PATH(@doc, 'one', '$.nickname') = 0 THEN 'missing'
    WHEN JSON_VALUE(@doc, '$.nickname') IS NULL THEN 'json-null'
    ELSE 'present'
  END AS state;

第一条查询的状态是 missing,第二条查询的状态是 json-null。如果把 nickname 改成 name,路径存在且取到普通字符串,就会得到 present。

JSON_CONTAINS_PATH 与 JSON_VALUE 组合判断 missing、json-null、present 三种状态的结构图
图2:用 JSON_CONTAINS_PATH 与 JSON_VALUE 组合得到三种业务状态的静态关系示意图,不是运行截图。

类型转换错误要单独设计

路径存在并不等于转换一定成功。例如目标类型指定为 UNSIGNED,而 JSON 值是普通字符串或数组,就会进入转换错误分支。不要把这种情况和缺失路径共用同一个默认值,否则数据质量问题会被悄悄吞掉。

-- 对数值字段保留可识别的错误默认值,避免和合法 0 混淆
SELECT JSON_VALUE(
  '{"count":"not-a-number"}',
  '$.count'
  RETURNING SIGNED
  NULL ON EMPTY
  DEFAULT -1 ON ERROR
) AS count_value;

这个例子把转换失败映射为 -1,但是否适合业务要看字段范围。如果负数也是合法值,应该改为错误返回,或额外输出错误标记。另一个重要边界是:JSON 文档或 JSON path 本身不是合法 JSON 时,属于输入语法错误,不能指望 ON ERROR 把所有问题都变成默认值。

上线前用一张表核对分支

在提交查询前,我会把最小基线固定成下面这张判断表。它比只看一行 SQL 更容易发现默认值与业务含义冲突:

场景推荐判断默认策略
路径不存在关注 ON EMPTY 或 JSON_CONTAINS_PATH()=0哨兵值或明确错误
路径存在且值为 JSON nullJSON_VALUE() IS NULL,并结合存在性判断保留 SQL NULL
路径存在且值为标量检查返回类型和长度正常业务值
值存在但类型转换失败关注 ON ERROR 与警告独立错误值或直接失败

如果只是临时报表,哨兵值通常够用;如果状态会驱动写入、统计或接口返回,显式保存存在性标记更稳。关键不是选择哪一个函数,而是不要让路径缺失、JSON null 和类型错误共享同一个业务含义。

常见问题

为什么 JSON_VALUE 找不到路径时也是 NULL?

因为默认行为是 NULL ON EMPTY。这是设计上的宽松默认值,不代表路径真的存在并且值为 JSON null。

能不能只用 IFNULL 区分缺失和 JSON null?

不能。IFNULL 只看到最终的 SQL NULL,无法恢复它来自缺失路径还是 JSON null。应该使用 ON EMPTY 哨兵或 JSON_CONTAINS_PATH。

ON EMPTY 和 ON ERROR 可以调换顺序吗?

不建议。标准写法把 ON EMPTY 放在前面;调换顺序可能触发语法错误或兼容性警告。

把查询拆成“路径存在性”和“标量提取”两层后,JSON_VALUE 的结果就不再是一个含义模糊的 NULL。先用三类输入建立基线,再根据业务是否允许哨兵值选择最小实现,排查和上线都更容易复核。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
MySQL GROUP BY WITH ROLLUP 识别小计与总计行的判断方法MySQL GROUP BY WITH ROLLUP 识别小计与总计行的判断方法
上一篇
MySQL GROUP BY WITH ROLLUP 识别小计与总计行的判断方法
MySQL 函数索引表达式不一致为什么不命中
下一篇
MySQL 函数索引表达式不一致为什么不命中
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    570次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    614次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    641次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    601次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    418次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码