MySQL JSON_EXTRACT 返回带引号怎样处理
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 转义
最容易被忽略的是名称本身就可能有双引号。比如品名里包含 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 或另加状态列,不要丢掉判断依据。

查询已经转换,接口为什么仍显示反斜杠?
SQL 结果、数据库驱动读取值和最终 HTTP JSON 响应,是不同边界。即使 SQL 已经返回普通文本,把它放进 JSON 响应时,序列化器仍然需要给字符串加引号,并转义字符串内部的引号;这是合法的响应编码,不一定是重复编码。
真正的问题是把已经序列化成 JSON 字符串的片段当成普通文本,再序列化一次。排查时我会看调用方实际解析后的字段,而不只看原始响应字节里有没有反斜杠。对查询层的取舍也保持克制:只是为了展示名称,就取文本;需要数字参与排序或计算,就定义数值类型转换和非法值规则,不能因为 ->> 去掉了引号就认定得到了数值。
如果该路径频繁用于筛选,去引号并不自动解决索引与执行计划问题。生成列或表达式索引需要另外按目标版本、类型、长度和比较规则设计;本文没有执行计划或性能测量,不声称替换一个函数就会更快。大小写、排序规则和字符长度也应与接口契约一起明确。
数组或对象调用 JSON_UNQUOTE 会展开成多行吗?
不会。它不是数组展开工具。若读取到容器,应保留 JSON、另选具体元素路径,或为展开任务使用相应方案,不要期待它自动变成业务名称。
SQL NULL 能用等号判断吗?
应使用 IS NULL 判断 SQL 空值;它不等于字符串 'null',也不能直接代替 JSON 类型判断。
什么情况下我会保留带引号的结果?
当后续仍按 JSON 值处理,或者调用方需要区分字符串、数字和容器时,我会保留 JSON_EXTRACT 的类型语义。展示字段的简洁不应以丢失数据含义为代价。
MySQL JSON_STORAGE_FREE 怎样判断部分更新留下的空间
- 上一篇
- MySQL JSON_STORAGE_FREE 怎样判断部分更新留下的空间
- 下一篇
- MySQL JSON 字段索引为什么没有命中
-
- 数据库 · MySQL | 28分钟前 | MySQL · 数据库开发 · mysql 递归CTE WITH RECURSIVE cte_max_recursion_depth 层级查询
- MySQL 递归 CTE 怎样设置层级停止条件
- 392浏览 收藏
-
- 数据库 · MySQL | 30分钟前 |
- MySQL CTE 怎样避免重复写复杂子查询
- 150浏览 收藏
-
- 数据库 · MySQL | 38分钟前 |
- MySQL JSON_SEARCH 怎样按通配符找到 JSON 字符串路径
- 288浏览 收藏
-
- 数据库 · MySQL | 44分钟前 | MySQL · JSON · 索引 · 性能 · explain · mysql 索引 JSON json_extract 生成列 JSON_UNQUOTE
- MySQL JSON 字段索引为什么没有命中
- 155浏览 收藏
-
- 数据库 · MySQL | 46分钟前 |
- MySQL JSON_STORAGE_FREE 怎样判断部分更新留下的空间
- 347浏览 收藏
-
- 数据库 · MySQL | 54分钟前 |
- MySQL 窗口函数怎样计算每组累计金额
- 172浏览 收藏
-
- 数据库 · MySQL | 22小时前 | 连接池 · 故障排查 · MySQL教程 · mysql 连接池 wait_timeout database/sql SetConnMaxIdleTime SetConnMaxLifetime 空闲连接 PingContext
- MySQL 连接池空闲连接失效 怎样处理
- 350浏览 收藏
-
- 数据库 · MySQL | 22小时前 | MySQL · 数据库 · csv · 数据导入 · CSV导入 MySQL LOAD DATA LOAD DATA LOCAL INFILE MySQL批量导入
- MySQL LOAD DATA 读取 CSV 怎样处理
- 307浏览 收藏
-
- 数据库 · MySQL | 22小时前 |
- MySQL 复制延迟区分线程 怎样处理
- 141浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 600次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 641次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 673次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 639次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 458次使用
-
- MySQL JSON_TABLE 展开数组时如何保留缺失字段
- 2026-09-10 501浏览
-
- MySQL 分区表怎么处理跨分区唯一键:分区列约束与建表取舍
- 2026-08-30 501浏览
-
- MySQL权限管理设置全攻略
- 2026-03-29 501浏览
-
- MySQL分片实现方法及常见方案解析
- 2025-06-24 501浏览
-
- MySQL表空间碎片怎么清理?超详细优化教程
- 2025-06-13 501浏览

