【问题标题】:Special characters on insert to postgres db with psql使用 psql 插入到 postgres db 的特殊字符
【发布时间】:2019-09-03 06:44:10
【问题描述】:

我尝试使用 psql 将特殊字符“†”添加到 varchar 字段,但没有成功。在 php 应用程序中它可以工作(php 用户为 iso8859-1)。

db 的设置是:

encoding = LATIN1
collation = fi_FI
character type = fi_FI
client both UTF8 & LATIN1 (on commandline PGCLIENTENCODING=LATIN1 or PGCLIENTENCODING=UTF8)

从表格中选择 当客户端是 UTF8 时显示

locationx \u0086

如何将值从 psql 添加到数据库?以下都不起作用。

update tablex set field1 = 'locationY' || '†'
update tablex set field1 = 'locationY' || U&'\86'

给出错误信息。

ERROR:  character with byte sequence 0xe2 0x80 0xa0 in encoding "UTF8" has no equivalent in encoding "LATIN1"
ERROR:  invalid Unicode escape value at or near "\86' "

如果我查看我的PHP应用程序输入的数据,字节是\x6c6f636174696f6e5986,但是当我用psql输入数据时,字节是\x6c6f636174696f6e59e280a0

【问题讨论】:

    标签: php postgresql character-encoding psql


    【解决方案1】:

    它不适用于 PHP 或 psql,因为字符 在 LATIN-1 编码中不存在。您只是无法将其存储在数据库中。

    让我解释一下发生了什么。

    • 如果您的客户端编码是LATIN1,而您输入的是psql

      INSERT INTO ... VALUES ('locationY†');
      

      成功存储,因为您的终端设置为 UTF-8。所以你输入的实际上是三个字节:\xE280A0,被解释和存储为三个单字节字符。

    • 如果你的客户端编码是UTF8,而你输入的是psql

      同样的插入会报错,因为你输入时输入的三个字节会被正确解释为匕首字符,而PostgreSQL尝试将字符转换为LATIN时会报错:

      ERROR:  character with byte sequence 0xe2 0x80 0xa0 in encoding "UTF8" has no equivalent in encoding "LATIN1"
      
    • 使用 PHP,您的客户端编码可能设置为LATIN1,而 PHP 程序实际上使用的是 WINDOWS-1252 编码。

      那么用单字节\x86表示。这由 PostgreSQL 在LATIN1 编码中解释,它意味着完全不同的东西,即“选定区域的开始”控制字符U+0086

      现在,当您的 PHP 程序读回该字符时,似乎一切正常,但数据库实际上存储的字符与您的预期不同。

      您会注意到,只要您尝试通过任何其他方式选择值,例如在您的 psql 控制台上。那里的值将呈现为

      locationY\u0086
      

    这是一个如何让事情正常工作的解决方案:

    • 使用UTF8 编码创建一个新数据库。

    • 转储旧数据库

      pg_dump -F p -E LATIN1 dbname
      
    • 手动编辑转储并更改行

      SET client_encoding = 'LATIN1';
      

      SET client_encoding = 'WIN1252';
      
    • 使用psql 将转储加载到新数据库中。

    • 将 PHP 应用程序的 client_encoding 更改为 WIN1252 并开始使用新数据库。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-13
      • 2016-11-24
      • 2015-02-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多