PostgreSQL字符集问题导致乱码

本文涉及的产品
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
简介:

在使用PostgreSQL数据库,输入中文时,会遇到“ERROR:  invalid byte sequence for encoding "UTF8": 0xd6d0”的错误,原因是由于没有正确设置客户端字符集。

 

问题的原因:

默认情况下,PostgreSQL是不转换字符集的,如果你的数据库是UTF8的字符集,一般终端的中文字符集会设置为GBK,或en_US(查看终端的字符集可以看LANG环境变量的设置),所以你输入的中文是GBK的编码,这个编码不经转换的存入数据库中,而数据库是UTF8的,PostgreSQL一看没有这样的UTF8编码,所以当然报错了。

解决方法为:

方法一:设置postgresql的客户端编码为GBK,这时PostgreSQL就知道输入的内容是GBK编码的,这样PostgreSQL数据库会自动做字符集的转换,把其转换成UTF8编码。

方法二:直接设置终端的字符集编码为UTF8,让输入的编码直接为UTF8,而不是GBK。

 

看我具体的演示:

 

方法一:设置postgresql的客户端编码:

设置psql客户端字符集为GBK,方法有两种,一种是在psql中输入“\encoding GBK” ,另一种是设置环境变量“export PGCLIENTENCODING=GBK”,演示:

[postgres@cacti ~]$ psql -d testdb03

psql.bin (9.5.9)

Type "help" for help.


testdb03=# \l

testdb03=# select * from weather;

   city   | temp_lo | temp_hi | prcp |    date    

----------+---------+---------+------+------------

 China07  |      49 |      61 |    3 | 1994-12-17

testdb03=# INSERT INTO weather (city, temp_lo, temp_hi, prcp, date) VALUES ('学校', '43', '10', '2.0', '1994-12-11');

INSERT 0 1

testdb03=# INSERT INTO weather (city, temp_lo, temp_hi, prcp, date) VALUES ('大学', '43', '10', '2.0', '1994-12-11');

INSERT 0 1

testdb03=# select * from weather;

   city   | temp_lo | temp_hi | prcp |    date    

----------+---------+---------+------+------------

 China07  |      49 |      61 |    3 | 1994-12-17

 学校     |      43 |      10 |    2 | 1994-12-11

 大学     |      43 |      10 |    2 | 1994-12-11


修改pgsql客户端字符集为GBK,再次查看表内容:

testdb03=# \encoding GBK

testdb03=# select * from weather;

   city   | temp_lo | temp_hi | prcp |    date    

----------+---------+---------+------+------------

 China07  |      49 |      61 |    3 | 1994-12-17

 У     |      43 |      10 |    2 | 1994-12-11

 ′    |      43 |      10 |    2 | 1994-12-11

(7 rows)

出现乱码,原因是psql数据库在初始化是指定的的字符集是utf8.

再次插入中文报错:

testdb03=# INSERT INTO weather (city, temp_lo, temp_hi, prcp, date) VALUES ('小学', '43', '10', '2.0', '1994-12-11');

ERROR:  character with byte sequence 0xad 0xa6 in encoding "GBK" has no equivalent in encoding "UTF8"


切换psql客户端的字符集为utf8字符集再次插入不再报错了:

testdb03=# \encoding UTF8

testdb03=# select * from weather;

   city   | temp_lo | temp_hi | prcp |    date    

----------+---------+---------+------+------------

 China07  |      49 |      61 |    3 | 1994-12-17

 学校     |      43 |      10 |    2 | 1994-12-11

 大学     |      43 |      10 |    2 | 1994-12-11

(7 rows)



testdb03=# INSERT INTO weather (city, temp_lo, temp_hi, prcp, date) VALUES ('小学', '43', '10', '2.0', '1994-12-11');

INSERT 0 1

testdb03=# select * from weather;

   city   | temp_lo | temp_hi | prcp |    date    

----------+---------+---------+------+------------

 China07  |      49 |      61 |    3 | 1994-12-17

 学校     |      43 |      10 |    2 | 1994-12-11

 大学     |      43 |      10 |    2 | 1994-12-11

 小学     |      43 |      10 |    2 | 1994-12-11

(8 rows)


testdb03=#



[postgres@cacti ~]$ export PGCLIENTENCODING=GBK

[postgres@cacti ~]$ psql -d testdb03

psql.bin (9.5.9)

Type "help" for help.


testdb03=# select * from weather;

   city   | temp_lo | temp_hi | prcp |    date    

----------+---------+---------+------+------------

 China07  |      49 |      61 |    3 | 1994-12-17

 У      |      43 |      10 |    2 | 1994-12-11

 ′      |      43 |      10 |    2 | 1994-12-11

 С      |      43 |      10 |    2 | 1994-12-11

(8 rows)


 testdb03=# INSERT INTO weather (city, temp_lo, temp_hi, prcp, date) VALUES ('小学', '43', '10', '2.0', '1994-12-11');

ERROR:  character with byte sequence 0xad 0xa6 in encoding "GBK" has no equivalent in encoding "UTF8"


修改回源字符集UTF8

[postgres@cacti ~]$ export PGCLIENTENCODING=UTF8

[postgres@cacti ~]$ 

[postgres@cacti ~]$ psql -d testdb03

psql.bin (9.5.9)

Type "help" for help.


testdb03=# \d

            List of relations

 Schema |     Name     | Type  |  Owner   

--------+--------------+-------+----------

 public | postgres_log | table | postgres

 public | weather      | table | postgres

(2 rows)


testdb03=# select * from weather;

   city   | temp_lo | temp_hi | prcp |    date    

----------+---------+---------+------+------------

 China07  |      49 |      61 |    3 | 1994-12-17

 学校     |      43 |      10 |    2 | 1994-12-11

 大学     |      43 |      10 |    2 | 1994-12-11

 小学     |      43 |      10 |    2 | 1994-12-11

(8 rows)


方法二:设置终端的编码为UTF8:

 

[postgres@dsc ~]$ export LANG=zh_CN.UTF8

 

然后修改终端软件的字符集编码,我使用的是SecureCRT,修改方法为:

Option->Session Option->外观->字符编码,把那个下拉框的内容改成“UTF8”:


然后再插入数据测试:


[postgres@dsc ~]$ psql -d testdb03

psql (8.4.3)

Type "help" for help.

testdb03=# select * from t;

 id |   name   

----+----------

  1 | 中国

  2 | 我的中国

(2 rows)

testdb03=# insert into t values(3,'我的中国');

INSERT 0 1

testdb03=# select * from t;                   

 id |   name   

----+----------

  1 | 中国

  2 | 我的中国

  3 | 我的中国

(3 rows)



 本文转自 wjw555 51CTO博客,原文链接:http://blog.51cto.com/wujianwei/1979023

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
SQL 关系型数据库 数据库
postgresql 字符集server_encoding变更
--今天在使用postgres_fdw做远端数据库转储时,发现本地所使用的字符集与远端是不同的,造成插入数据错误 postgres=# insert into t select * from...
1563 0
|
SQL 关系型数据库 数据库
PostgreSQL sql文件编码引起的数据导入乱码或查询字符集异常报错(invalid byte sequence)
标签 PostgreSQL , 乱码 , 文件编码 背景 当用户客户端字符集与服务端字符集不匹配时,写入的多字节字符(例如中文)可能出现乱码。 例子 数据库字符集为sql_ascii,允许存储任意编码字符。
3702 0
|
关系型数据库 Unix 数据库
PostgreSQL 10.1 手册_部分 III. 服务器管理_第 23 章 本地化_23.3. 字符集支持
23.3. 字符集支持 23.3.1. 被支持的字符集 23.3.2. 设置字符集 23.3.3. 服务器和客户端之间的自动字符集转换 23.3.4. 进一步阅读 PostgreSQL里面的字符集支持你能够以各种字符集存储文本,包括单字节字符集,比如 ISO 8859 系列,以及多字节字符集 ,比如EUC(扩展 Unix 编码 Extended Unix Code)、UTF-8 和 Mule 内部编码。
1241 0
|
关系型数据库 Linux PostgreSQL
|
关系型数据库 数据库 PostgreSQL
初学者遇到的PostgreSQL字符集问题的解决
当初学者在使用PostgreSQL数据库,输入中文时,会遇到“ERROR:  invalid byte sequence for encoding "UTF8": 0xd6d0”的错误,原因是由于没有正确设置客户端字符集。
2509 0
|
存储 关系型数据库 Java
RDS for MySQL 使用 utf8mb4 字符集存储 emoji 表情
RDS for MySQL 使用 utf8mb4 字符集存储 emoji 表情
6908 0
|
SQL Cloud Native 关系型数据库
ADBPG(AnalyticDB for PostgreSQL)是阿里云提供的一种云原生的大数据分析型数据库
ADBPG(AnalyticDB for PostgreSQL)是阿里云提供的一种云原生的大数据分析型数据库
1254 1
|
数据可视化 关系型数据库 MySQL
将 PostgreSQL 迁移到 MySQL 数据库
将 PostgreSQL 迁移到 MySQL 数据库
1754 2
|
SQL 存储 自然语言处理
玩转阿里云RDS PostgreSQL数据库通过pg_jieba插件进行分词
在当今社交媒体的时代,人们通过各种平台分享自己的生活、观点和情感。然而,对于平台管理员和品牌经营者来说,了解用户的情感和意见变得至关重要。为了帮助他们更好地了解用户的情感倾向,我们可以使用PostgreSQL中的pg_jieba插件对这些发帖进行分词和情感分析,来构建一个社交媒体情感分析系统,系统将根据用户的发帖内容,自动判断其情感倾向是积极、消极还是中性,并将结果存储在数据库中。
玩转阿里云RDS PostgreSQL数据库通过pg_jieba插件进行分词