繁体   English   中英

使用 psql 插入 postgres db 时的特殊字符

[英]Special characters on insert to postgres db with psql

我尝试将特殊字符“†”与 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 或psql ,因为字符在 LATIN-1 编码中不存在。 您只是无法将其存储在数据库中。

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

  • 如果您的客户端编码是LATIN1并且您输入psql

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

    成功存储,因为您的终端设置为 UTF-8。 因此,您键入的实际上是三个字节: \\xE280A0 ,它们被解释并存储为三个单字节字符。

  • 如果您的客户端编码是UTF8并且您输入psql

    同样的insert会报错,因为输入时输入的三个字节会被正确解释为dagger字符,而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\†

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

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

  • 转储旧数据库

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

    SET client_encoding = 'LATIN1';

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM