SQL基础教程系列_基于Postgresql_创建表时的中文乱码问题(附如何修改注册表更改dos encoding方式)

创建表时的中文乱码问题:具体分为两种,一种是输入进去就不显示中文,第二种是当上传到服务器端会返回乱码。具体原因可以参考: http://www.cnblogs.com/winkey4986/p/6279243.html (一篇博客)及 http://www.postgres.cn/docs/9.5/multibyte.html (官方字符集支持documentation)以下为总结:

1.数据库编程的编码问
数据库编程设计的编码问题包括三个方面:
    数据库服务器编码;
    数据库客户端编码;
    本地环境编码。


1.1 数据库服务器字符编码:
数据库服务器支持某种编码,是指数据库服务器能够从客户端接收、存储以及向客户端提供该种编码的字符,并能将该种编码的字符转换到其它编码。

查看PostgreSQL数据库服务器端编码:

postgres=# show server_encoding;
 server_encoding 
-----------------
 UTF8
postgres=# \l
   名称    |  拥有者   | 字元编码 |                       Collate                       |                        Ctype                        |        TestDb1   | TestRole1 | UTF8     | Chinese (Simplified)_People's Republic of China.936 | Chinese (Simplified)_People's Republic of China.936 | 
 TestDb2   | postgres  | UTF8     | Chinese (Simplified)_People's Republic of China.936 | Chinese (Simplified)_People's Republic of China.936 | 
 postgres  | postgres  | UTF8     | Chinese (Simplified)_People's Republic of China.936 | Chinese (Simplified)_People's Republic of China.936 | 
 template0 | postgres  | UTF8     | Chinese (Simplified)_People's Republic of China.936 | Chinese (Simplified)_People's Republic of China.936 | 


1.2 数据库客户端字符编码:
 客户端工具支持某种编码,必须能够显示从数据库读取的该种编码的字符,也能通过本工具将该种编码的字符提交到给服务器端。

查看PostgreSQL客户端工具psql编码:

 postgres=# show client_encoding;
 GBK
 postgres=# \encoding
 GBK


 指定Postgresql会话的客户端编码:

 postgres=# set client_encoding to 'utf8';
 SET
 postgres=# show client_encoding;
 client_encoding 
 -----------------
 UTF8


 1.3 本地环境编码:
如果使用dos的命令行界面,本地环境就是指dos命令行环境的编码,可以使用dos命令chcp查看dos环境编码:

D:\Program Files\PowerCmd>chcp
活动代码页: 936
----936为简体中文,GBK;

如果在使用某种编辑器,则本地环境编码取该编辑器的编码设置。

   1.3.1 修改dos命令行编码方式:

       1.3.1.1 临时修改,只作用于当前打开的窗口

            进入cmd窗口后,直接执行“chcp 65001”

            执行完后,cmd的编码格式就是UTF-8

       1.3.1.2 永久修改,修改注册表。

            在运行中输入"regedit",找到HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor

            然后“右键-新建”,选择“字符串值”,“名称”列填写“autorun”, 数值数据填写“@chcp65001>null”   --for windows 10

2 示例
2.1 示例1

2.1.1 设置

PostgreSQL的数据库postgres,

服务器端字符编码:utf8,

客户端工具psql字符编码:gbk,

本地环境dos命令编辑器编码:gbk,此时:

postgres=# show server_encoding;
 server_encoding 
-----------------
 UTF8
(1 行记录)
postgres=# show client_encoding;
 client_encoding 
-----------------
 GBK
(1 行记录)
postgres=# \! chcp
活动代码页: 936
postgres=# select * from "TestTb1";
  Column1                                                               
-----------


2.1.2 分析

由于本地环境和客户端编码都是GBK,一致,没有问题。

insert时,客户端接收本地环境输入的GBK字符(两者都为GBK),客户端传到服务器端时自动转换为UTF-8编码存储,没有问题。

select时,服务器端传到客户端,UTF-8编码自动转换为GBK编码,在本地环境显示时,本地环境就是GBK编码,显示没有问题。(编码方式互相支持的转换在官方文档里有提及)

2.2 示例2

2.2.1 设置

PostgreSQL的数据库postgres,

服务器端字符编码:utf8,

客户端工具psql字符编码:utf8,

本地环境dos命令编辑器编码:GBK,此时:

postgres=# set client_encoding to 'utf8';
SET
postgres=# insert into test values('测试1');
閿欒?:  鏃犳晥鐨?"UTF8" 缂栫爜瀛楄妭椤哄簭: 0xb2
postgres=# select * from test;
      column1
--------------------
 娴嬭瘯
(1 行记录)                                   

2.2.2 分析                                                                
由于客户端和服务器的编码一致,故不进行转码。

insert时,本地输入的GBK编码到客户端不自动转换,而客户端又把接收到的没转换编码方式的字符当作utf编码直接传给服务器端且也没有转换,这时服务器就将GBK编码的字符作为UTF-8编码的字符存储,故有问题。报错的信息为:ERROR:  invalid byte sequence for encoding "UTF8": 0xb2;

select时,服务端的utf编码传给客户端不转换,客户端把utf编码传给本地环境不自动转换,utf8编码用gbk编码显示,故有问题。

2.2.3 结论

虽然PG支持客户端和服务器端的编码自动转换,但是本地环境的编码方式到客户端并不会自动转换,所以还需要遵从一个原则:本地环境的编码和客户端编码需一致。

3.总结

①直接在psql执行insert或者select的时候,设置client_encoding=gbk(默认),dos命令行编码方式=gbk(本地环境的编码和客户端编码需一致),server_encoding=utf8 

②使用“\i sql文件.sql”(sql文件是utf8编码)命令的时候,如果sql文件中有中文,一定要先行执行set client_encoding=utf8;(设置此之后,按照上面说的,客户端不转换,直接把接收的字符作为utf8编码传给服务器端,而文件本身就是utf8,所以不乱码;同理如果sql文件是ansi编码即gbk编码的话,确保client_encoding为gbk;总之,sql文件与client_encoding编码一致),才不乱码。

 

ref:http://www.cnblogs.com/winkey4986/p/6279243.html 

        http://www.postgres.cn/docs/9.5/multibyte.html 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值