根本原因是select未包裹在json函数中或数据库版本不支持原生json导出;mysql 5.7+、postgresql 9.2+、sql server 2016+才具备可靠内置能力,旧版需应用层拼接。
where 条件写对了,但导出 json 为空?
根本原因通常是 select 没包在 json 函数里,或者数据库不支持原生 json 导出。mysql 5.7+、postgresql 9.2+、sql server 2016+ 才有靠谱的内置 json 构造能力;老版本得靠应用层拼接。
- MySQL 用
JSON_OBJECT()或JSON_ARRAYAGG()包裹字段,不能只写SELECT name, age FROM user WHERE status = 'active' - PostgreSQL 更直接,
row_to_json()或json_agg()配合WHERE即可,但注意子查询别漏AS别名 - SQLite 没原生 JSON 函数,强行用
json_object()需要编译时开启 JSON1 扩展,否则运行时报错no such function: json_object
MySQL 导出单条记录为 JSON 的正确写法
想导出 id = 123 的用户为一行 JSON?别用 SELECT JSON_OBJECT('id', id, 'name', name) FROM user WHERE id = 123 然后手动复制——它可能返回多行(比如有 NULL 字段),且没换行/缩进。
- 加
JSON_PRETTY()让结果可读:SELECT JSON_PRETTY(JSON_OBJECT('id', id, 'name', name, 'email', email)) FROM user WHERE id = 123 - 如果字段可能为 NULL,
JSON_OBJECT()默认跳过,要用COALESCE()补默认值,否则前端解析易报错 - 导出到文件别依赖客户端“另存为”,用命令行更稳:
mysql -u root -p -e "SELECT JSON_PRETTY(...)" database_name > output.json,注意引号嵌套和 shell 转义
PostgreSQL 中 WHERE + json_agg() 导出多条数据的坑
json_agg() 看似简单,但一加 WHERE 就容易导出空数组 [] 或直接报错,尤其当条件没匹配到任何行时。
- 空结果集下
json_agg()返回NULL,不是[],需用COALESCE(json_agg(...), '[]'::json)强制兜底 - 若字段含特殊字符(如换行、双引号),PostgreSQL 默认会转义,但某些旧版 psql 客户端导出时可能截断,建议加
\t选项禁用表头:psql -t -c "SELECT COALESCE(...)" > data.json - 别在
json_agg()外再套一层row_to_json(),会导致嵌套一层无意义对象,生成类似{"?column?": [...]}
导出大结果集时 JSON 内存爆掉或超时
查 10 万行转 JSON,MySQL 可能报 Packet too large,PostgreSQL 可能卡死或 OOM——JSON 构造是内存密集型操作,不是流式生成。
- MySQL 设置临时增大:
SET SESSION max_allowed_packet = 512 * 1024 * 1024,但治标不治本 - 更可靠的是分页导出:用
LIMIT+OFFSET或游标(如id > last_id),每次导出 1000 行,拼成多个 JSON 文件再合并 - 真正海量数据(百万级以上),放弃 SQL 直出 JSON,改用程序语言(Python/Go)逐行 fetch +
json.dump()流式写入,内存可控、错误可捕获
最常被忽略的一点:导出前没验证字符集。如果数据库是 latin1,而 JSON 含中文,最终文件里就是乱码 \uXXXX 或直接报错,务必确认连接和表字符集都是 utf8mb4。











