根本原因是客户端与服务端字符集协商失败,需确保数据库编码为UTF8、连接字符串添加options=-c%20client\_encoding%3DUTF8、SQL编辑器设为UTF-8编码、导出CSV选UTF-8 with BOM,并避免使用无效的ALTER DATABASE SET client_encoding。
Navicat 连 PostgreSQL 时中文显示为问号或方块
根本原因是客户端(navicat)与 postgresql 服务端的字符集协商失败,不是单纯改 navicat 字体就能解决的。postgresql 的 client_encoding 默认继承自数据库创建时的编码(通常是 utf8),但 navicat 可能没正确声明自己支持 utf-8,或者连接字符串里漏了关键参数。
实操建议:
- 检查数据库实际编码:
SELECT pg_encoding_to_char(encoding) FROM pg_database WHERE datname = current_database();
确保返回UTF8;如果不是,重建数据库或迁移数据,别硬调客户端 - 在 Navicat 连接配置里,点「高级」→ 勾选「使用 SSL 连接」下方的「运行前执行命令」,填入:
SET client_encoding TO 'UTF8';
- 更可靠的做法:编辑连接的「SSH/SSL」页签 → 「连接字符串」栏末尾追加
options=-c%20client_encoding%3DUTF8(注意 URL 编码,%20是空格,%3D是等号) - 避免用 Windows 自带的「GBK」区域设置连 Linux 上的 PostgreSQL——即使 Navicat 显示“连接成功”,
INSERT中文后查出来仍是乱码,因为协议层已错位
Navicat 新建查询窗口里输入中文直接变空格或报错
这通常发生在 Navicat 使用了非 UTF-8 的默认字符集启动,尤其 Windows 用户装了中文版 Navicat 后没动过编码设置,它会默认用系统 ANSI(如 GBK)读写 SQL 文本,但发给 PostgreSQL 时又按 UTF-8 解释,字节流对不上。
实操建议:
- 关闭所有查询窗口,进 Navicat「工具」→「选项」→「外观」→「字体」,把「SQL 编辑器字体」改成支持 UTF-8 的(比如
Consolas或Microsoft YaHei),并确认「编码」下拉框选的是UTF-8(不是GBK或Auto) - 新建查询窗口后,先手动执行:
SHOW client_encoding;
如果返回SQL_ASCII或GBK,说明前面的连接参数没生效,得回头检查「运行前执行命令」是否拼错或被禁用 - 不要依赖 Navicat 的「自动检测编码」功能——它常把 UTF-8 BOM 识别成 GBK,一保存就毁数据
从 Navicat 导出 CSV 含中文,用 Excel 打开全是乱码
这不是 PostgreSQL 的问题,是 Excel 默认用系统编码(Windows 是 GBK)打开无 BOM 的 UTF-8 文件。Navicat 导出时选「UTF-8」只是指文件内容编码,不等于 Excel 能认出来。
实操建议:
- 导出时在 Navicat「导出向导」里,「格式」选
CSV→ 下一步 → 「编码」务必选UTF-8 with BOM(有 BOM 选项才有效) - 如果只有「UTF-8」没 BOM 选项(老版本 Navicat),导出后用 VS Code 或 Notepad++ 手动转存为
UTF-8 with BOM,再给 Excel - 别用 Excel 直接双击打开 CSV——用 Excel 启动后,「数据」→「从文本/CSV」→ 选择文件 → 在导入向导里手动指定「文件原始编码」为
65001: Unicode (UTF-8)
ALTER DATABASE SET client_encoding 不起作用
ALTER DATABASE ... SET client_encoding 是无效操作,PostgreSQL 不允许全局设置客户端编码。这个参数只在会话级(SET client_encoding)或连接参数中生效,数据库级配置表里根本没有这一项。
实操建议:
- 别试
ALTER DATABASE mydb SET client_encoding = 'UTF8';—— 它不会报错,但也不会生效,属于静默忽略 - 真正要持久化,只能靠连接串参数(如前面说的
options=-c%20client_encoding%3DUTF8)或应用层代码里显式SET client_encoding - 如果用的是 PostgreSQL 14+,可以考虑在
postgresql.conf里设client_encoding = utf8,但这会影响所有客户端,且 Navicat 这类 GUI 工具可能仍会覆盖它
最易被忽略的一点:Navicat 的「连接测试」按钮只验证网络和认证,不校验字符集是否真正协商成功。必须执行一条含中文的 SELECT 或 INSERT 才算真实通过。










