Go语言“unexpected end of JSON input”错误及NULL字段处理需求
解决MariaDB输出JSON时省略NULL字段的问题
我完全懂你这个需求——数据库里的可选字段存NULL时,输出JSON就不想带着这些占位置的键对吧?之前试过替换默认值没用,因为核心是要省略字段而不是替换值,在MariaDB里确实得用针对性的JSON函数来处理,我给你几个实用的方案:
方案1:从普通字段生成JSON时自动省略NULL(通用版本)
如果你是从常规表字段生成JSON对象,不想包含NULL值的字段,可以用JSON_MERGE_PATCH结合条件判断来动态构建。比如假设你的表有必填字段id、name,可选字段description、price:
SELECT id, JSON_MERGE_PATCH( -- 基础必填字段的JSON JSON_OBJECT('id', id, 'name', name), -- 仅当description非NULL时才合并这个字段 IF(description IS NOT NULL, JSON_OBJECT('description', description), JSON_OBJECT()), -- 仅当price非NULL时才合并这个字段 IF(price IS NOT NULL, JSON_OBJECT('price', price), JSON_OBJECT()) ) AS cleaned_json FROM your_table;
JSON_MERGE_PATCH会把多个JSON对象合并成一个,空的JSON_OBJECT()不会添加任何键,完美实现只保留非NULL字段的效果。
方案2:处理已存储的JSON数组(LongText类型)
如果你的数据已经是存在LongText里的JSON数组,想要清理每个对象里的NULL字段,可以先把数组拆成单个对象,处理完再重新聚合:
SELECT JSON_ARRAYAGG(processed_obj) AS cleaned_json_array FROM ( SELECT JSON_MERGE_PATCH( JSON_OBJECT('id', j.id), IF(j.opt_field1 IS NOT NULL, JSON_OBJECT('opt_field1', j.opt_field1), JSON_OBJECT()), IF(j.opt_field2 IS NOT NULL, JSON_OBJECT('opt_field2', j.opt_field2), JSON_OBJECT()) ) AS processed_obj FROM your_data_table, -- 把JSON数组拆成一行一行的对象 JSON_TABLE( your_json_column, '$[*]' COLUMNS( id INT PATH '$.id', opt_field1 VARCHAR(255) PATH '$.opt_field1', opt_field2 VARCHAR(255) PATH '$.opt_field2' ) ) AS j ) AS subquery;
注意这里要把your_json_column里的所有字段都在JSON_TABLE里定义出来,这样才能逐个判断是否为NULL。
方案3:MariaDB 10.6+ 更简洁的写法
如果你的MariaDB版本在10.6及以上,可以用JSON_TRANSFORM直接删除NULL值的键,语法更直观:
-- 处理单个JSON对象 SELECT JSON_TRANSFORM( '{"id":1, "opt1":null, "opt2":"test"}', '$.opt1' DELETE IF EXISTS AND @.opt1 IS NULL, '$.opt2' DELETE IF EXISTS AND @.opt2 IS NULL ) AS cleaned_obj; -- 处理JSON数组的话,结合JSON_TABLE和JSON_TRANSFORM再聚合即可
额外排查点
你之前提到有报错,可能的原因:
- 存储的LongText内容不是合法JSON:可以用
SELECT JSON_VALID(your_json_column) FROM your_table;检查,返回1是合法,0是非法 - 使用了低版本不支持的函数:比如
JSON_TABLE是10.2.3+才支持,JSON_TRANSFORM是10.6+,确认下你的MariaDB版本
内容的提问来源于stack exchange,提问作者Sap
相关产品推荐
相关产品推荐

