当前位置:首页 > 文章列表 > 数据库 > MySQL > MySQL JSON_EXTRACT 返回带引号怎样处理

MySQL JSON_EXTRACT 返回带引号怎样处理

来源:17golang原创 2026-10-23 03:52:56 0浏览 收藏

MySQL 的 JSON_EXTRACT 返回字符串时带双引号,是因为它返回 JSON 值,而 JSON 字符串的表示本来就包含引号。需要普通文本时,使用 JSON_UNQUOTE(JSON_EXTRACT(doc, '$.name'));若 doc 是 JSON 列,也可写成 doc->>'$.name'。不要用 REPLACE 删除所有双引号,那会把内容里的合法字符也删掉。

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

先决定返回的是 JSON 还是业务文本,再选择提取表达式。去引号只解决字符串表示,不能替你决定缺失字段、JSON null、数字和数组应该如何映射。

如果是我接手这个字段,会先问调用方要什么

设想一个商品目录查询,JSON 文档中存着商品名称,页面只想展示名称,却拿到了带引号的结果。这里是教学场景,不是本人线上事故或实测记录。我的取舍会先从接口契约开始:如果调用方还要继续做 JSON 运算,我会保留 JSON 值;如果它只需要展示文本,我会在查询边界明确转换。

我不倾向于在每个页面再写一次“删引号”的补丁。这样看起来改动小,但接口、报表和导出容易得到不同结果。对我来说,明确一个字段的返回类型比让某个客户端表格暂时好看更重要;不过,通用 JSON 浏览器需要保留类型信息,就不适合把所有值都一律转成字符串。

两种表达式看起来相近,职责并不相同

以下查询只用表达式构造文档,不建表、不修改业务数据。示例按 MySQL 8.4 文档语义说明,没有在本机执行,结果描述是供读者运行时对照的预期。

-- JSON_OBJECT 构造本次原创样例,分别观察 JSON 值、文本和类型
SELECT
    JSON_EXTRACT(doc, '$.name') AS name_json,
    JSON_UNQUOTE(JSON_EXTRACT(doc, '$.name')) AS name_text,
    JSON_TYPE(JSON_EXTRACT(doc, '$.name')) AS name_kind
FROM (
    SELECT JSON_OBJECT('name', '轻量收纳盒', 'stock', 24) AS doc
) AS sample;

预期 name_json 表示 JSON 字符串,name_text 是普通名称文本,name_kind 为 STRING。客户端可能对字符串再加显示装饰,因此不要只靠界面里的引号判断 SQL 返回类型。先看表达式,再看类型和应用读取方式。

业务要求表达式选择需要接受的边界
保留 JSON 类型做后续运算JSON_EXTRACT字符串保持 JSON 表示
提取名称等文本JSON_UNQUOTE(JSON_EXTRACT(...))返回文本,仍需制定缺失策略
固定 JSON 列与固定路径的简洁写法列 ->> 路径是解引号提取,不代表数值类型转换
JSON 文档、提取表达式与文本返回契约的静态关系
图1:返回契约结构图。保留 JSON 与提取文本是两种用途,不是截图或实测结果。

我不会用字符串替换去修 JSON 转义

最容易被忽略的是名称本身就可能有双引号。比如品名里包含 12" 收纳盒,JSON 表示会对其中的引号做转义;它不是多余字符。删掉所有双引号,或者机械截掉首尾字符,都没有真正执行 JSON 字符串解码。

-- 用 CHAR(34) 构造合法双引号,避免手写多层反斜杠
SELECT
    JSON_EXTRACT(doc, '$.name') AS encoded_value,
    JSON_UNQUOTE(JSON_EXTRACT(doc, '$.name')) AS decoded_text
FROM (
    SELECT JSON_OBJECT('name', CONCAT('12', CHAR(34), ' 收纳盒')) AS doc
) AS sample;

decoded_text 预期保留名称中真正的双引号,而不是把它删除。需要特别注意 SQL 字符串字面量与 JSON 转义是两层规则;手写反斜杠的示例还可能受 SQL mode 影响。这里用 JSON_OBJECT 和 CHAR 构造输入,重点放在返回类型,不让转义层数盖过问题本身。

缺失、JSON null 和字符串 null 不能混成一种值

只看解引号后的文字,有时无法区分原始类型。例如 JSON null 与字符串 "null" 在转换成文本后容易被调用方混淆。路径根本不存在又是另一种情况。我的建议是:名称字段先限制为 JSON STRING,其他情况按业务映射为 SQL NULL,必要时另外输出状态字段。

-- 五组输入分别保留原始 JSON 类型,只把真正的字符串作为名称
WITH samples AS (
    SELECT 1 AS id, JSON_OBJECT('name', '轻量收纳盒') AS doc
    UNION ALL SELECT 2, JSON_OBJECT('name', NULL)
    UNION ALL SELECT 3, JSON_OBJECT('name', 'null')
    UNION ALL SELECT 4, JSON_OBJECT()
    UNION ALL SELECT 5, JSON_OBJECT('name', 24)
),
extracted AS (
    SELECT id, JSON_EXTRACT(doc, '$.name') AS value_json
    FROM samples
)
SELECT
    id,
    JSON_TYPE(value_json) AS value_kind,
    value_json IS NULL AS is_sql_null,
    CASE
        -- 只接受字符串;JSON null、路径缺失和错误业务类型均不冒充名称
        WHEN JSON_TYPE(value_json) = 'STRING'
        THEN JSON_UNQUOTE(value_json)
        ELSE NULL
    END AS name_text
FROM extracted
ORDER BY id;

按这份名称契约,第 1、3 行返回文本,其中第 3 行的 null 是四个字母,不是空值。第 2 行原始类型为 JSON 的 NULL,第 4 行路径缺失得到 SQL NULL,第 5 行原始类型是整数;这三行的 name_text 都映射为 SQL NULL。这里主动合并了非字符串情况,若业务需要分别报“未填写”与“类型错误”,就保留 value_kind 或另加状态列,不要丢掉判断依据。

路径缺失、JSON null、字符串及类型约束的静态关系
图2:类型策略结构图。业务文本与原始 JSON 类型分开表达,不把 null 文字误作空值。

查询已经转换,接口为什么仍显示反斜杠?

SQL 结果、数据库驱动读取值和最终 HTTP JSON 响应,是不同边界。即使 SQL 已经返回普通文本,把它放进 JSON 响应时,序列化器仍然需要给字符串加引号,并转义字符串内部的引号;这是合法的响应编码,不一定是重复编码。

真正的问题是把已经序列化成 JSON 字符串的片段当成普通文本,再序列化一次。排查时我会看调用方实际解析后的字段,而不只看原始响应字节里有没有反斜杠。对查询层的取舍也保持克制:只是为了展示名称,就取文本;需要数字参与排序或计算,就定义数值类型转换和非法值规则,不能因为 ->> 去掉了引号就认定得到了数值。

如果该路径频繁用于筛选,去引号并不自动解决索引与执行计划问题。生成列或表达式索引需要另外按目标版本、类型、长度和比较规则设计;本文没有执行计划或性能测量,不声称替换一个函数就会更快。大小写、排序规则和字符长度也应与接口契约一起明确。

数组或对象调用 JSON_UNQUOTE 会展开成多行吗?

不会。它不是数组展开工具。若读取到容器,应保留 JSON、另选具体元素路径,或为展开任务使用相应方案,不要期待它自动变成业务名称。

SQL NULL 能用等号判断吗?

应使用 IS NULL 判断 SQL 空值;它不等于字符串 'null',也不能直接代替 JSON 类型判断。

什么情况下我会保留带引号的结果?

当后续仍按 JSON 值处理,或者调用方需要区分字符串、数字和容器时,我会保留 JSON_EXTRACT 的类型语义。展示字段的简洁不应以丢失数据含义为代价。

参考:JSON 提取与解引号操作符;JSON_UNQUOTE;JSON_TYPE。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
MySQL JSON_STORAGE_FREE 怎样判断部分更新留下的空间MySQL JSON_STORAGE_FREE 怎样判断部分更新留下的空间
上一篇
MySQL JSON_STORAGE_FREE 怎样判断部分更新留下的空间
MySQL JSON 字段索引为什么没有命中
下一篇
MySQL JSON 字段索引为什么没有命中
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之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模型性能。
    600次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    641次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    673次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    639次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    458次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码