猿问

使用 psql 插入 postgres 数据库时的特殊字符

我尝试将特殊字符“†”与 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.


森林海
浏览 578回答 1
1回答

慕桂英3389331

它不适用于 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\u0086这是如何使事情正常工作的解决方案:创建一个带有UTF8编码的新数据库。转储旧数据库pg_dump -F p -E LATIN1 dbname手动编辑转储并更改行SET client_encoding = 'LATIN1';到SET client_encoding = 'WIN1252';将转储加载到新数据库中psql。将client_encoding您的 PHP 应用程序更改为WIN1252并开始使用新数据库。
随时随地看视频慕课网APP
我要回答