2014-09-24 64 views
1

错误地存储UTF-8值在9.1的Postgres 我导入数据只(无结构)成UTF-8 DB包含没有记录Postgres的导入时

psql -l给我

Name | Owner | Encoding | Collate | Ctype | Access privileges 
-----------+----------+----------+-------------+-------------+----------------------- 
glyph  | glyph | UTF8  | en_GB.UTF-8 | en_GB.UTF-8 | =Tc/glyph   + 
      |   |   |    |    | glyph=CTc/glyph 

的表看起来像这样:从我的SQL文件

-- Table: sign 

-- DROP TABLE sign; 

CREATE TABLE sign 
(
    id serial NOT NULL, 
    sign_ref character varying(150) NOT NULL, 
    CONSTRAINT pk_sign PRIMARY KEY (id) 
) 
WITH (
    OIDS=FALSE 
); 
ALTER TABLE sign 
    OWNER TO glyph; 

-- Index: ix_sign_sign_ref 

-- DROP INDEX ix_sign_sign_ref; 

CREATE UNIQUE INDEX ix_sign_sign_ref 
    ON sign 
    USING btree 
    (sign_ref COLLATE pg_catalog."default"); 

价值加入:
命令:psql -h localhost -d glyph -U glyph -f import.sql

START TRANSACTION; 
SET standard_conforming_strings=off; 
SET escape_string_warning=off; 
SET CONSTRAINTS ALL DEFERRED; 
INSERT INTO "sign" VALUES (29585,'DE₂'); 
COMMIT; 

但是,这已被转换为数据库中的“DEâ”。 我做错了什么?

编辑:

select convert_to(
(select sign_ref from sign where id = 29585), 'utf8'); 

给我:
DE\303\242\302\202\302\202

+0

你可以添加'选择convert_to(sign_ref,“utf-8”)的结果'作为什么在以字节为单位的分贝证据? – 2014-09-24 15:24:26

+0

@DanielVérité完成,请参阅编辑。 – urschrei 2014-09-24 15:36:57

回答

3

的问题是输入(INSERT查询)在UTF-8被编码而是解释为LATIN1(或LATIN9),可能因为错误的client_encoding设置。

推理的行是:

  1. DE₂以UTF-8字节表示是44 45 E2 82 82(十六进制)
  2. 当LATIN1解释,这些字节意味着DEâ和两个控制字符0x82。这就是进入数据库的原因。
  3. 当用正常的utf-8重新读取它时,得到的结果是在utf-8中编码的â,后面跟着两个用utf-8编码的U + 0082。在十六进制字节中,即44 45 c3 a2 c2 82 c2 82.在八进制中,这就是DE\303\242\302\202\302\202,这与convert_to(sign_ref, 'utf-8')正好相同。

演示与UTF8终端:

$ cat > test.sql 
create table test(t text); 
set client_encoding to latin1; -- intentional mistake for the purpose of demoing 
insert into test values('DE₂'); 

$ psql -d test -f test.sql 

$ psql -d test 
select * from test; 
     t   
----------------- 
DEâ\u0082\u0082 

set bytea_output='escape'; 

select convert_to(t, 'utf-8') from test; 
     convert_to   
---------------------------- 
DE\303\242\302\202\302\202 
+0

正确设置客户端编码工作。谢谢! – urschrei 2014-09-25 11:25:49