天天看點

PostgreSQL字元集問題導緻亂碼

在使用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');

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

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

修改pgsql用戶端字元集為GBK,再次檢視表内容:

testdb03=# \encoding GBK

 У     |      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

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

(8 rows)

testdb03=#

[postgres@cacti ~]$ export PGCLIENTENCODING=GBK

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

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

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

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

修改回源字元集UTF8

[postgres@cacti ~]$ export PGCLIENTENCODING=UTF8

[postgres@cacti ~]$ 

testdb03=# \d

            List of relations

 Schema |     Name     | Type  |  Owner   

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

 public | postgres_log | table | postgres

 public | weather      | table | postgres

(2 rows)

方法二:設定終端的編碼為UTF8:

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

然後修改終端軟體的字元集編碼,我使用的是SecureCRT,修改方法為:

Option->Session Option->外觀->字元編碼,把那個下拉框的内容改成“UTF8”:

然後再插入資料測試:

[postgres@dsc ~]$ psql -d testdb03

psql (8.4.3)

testdb03=# select * from t;

 id |   name   

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

  1 | 中國

  2 | 我的中國

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

testdb03=# select * from t;                   

  3 | 我的中國

(3 rows)

 本文轉自 wjw555 51CTO部落格,原文連結:http://blog.51cto.com/wujianwei/1979023