1 回答

TA貢獻2036條經(jīng)驗 獲得超8個贊
它不適用于 PHP 或psql
,因為該字符?
在 LATIN-1 編碼中不存在。您只是無法將其存儲在數(shù)據(jù)庫中。
讓我解釋一下發(fā)生了什么。
如果您的客戶端編碼是
LATIN1
并且您輸入psql
:INSERT INTO ... VALUES ('locationY?');
成功存儲,因為您的終端設(shè)置為 UTF-8。所以
?
你輸入的實際上是三個字節(jié):\xE280A0
,它們被解釋和存儲為三個單字節(jié)字符。如果您的客戶端編碼是
UTF8
并且您輸入psql
:同樣的insert會報錯,因為輸入時輸入的三個字節(jié)
?
會被正確解釋為dagger字符,而PostgreSQL嘗試將字符轉(zhuǎn)換為 時會報錯LATIN
:ERROR: character with byte sequence 0xe2 0x80 0xa0 in encoding "UTF8" has no equivalent in encoding "LATIN1"
使用 PHP,您的客戶端編碼可能設(shè)置為
LATIN1
,而 PHP 程序?qū)嶋H上使用的是 WINDOWS-1252 編碼。然后
?
由單個字節(jié)表示\x86
。這是由 PostgreSQL 在LATIN1
編碼中解釋的,它意味著完全不同的東西,即“所選區(qū)域的開始”控制字符U+0086
。現(xiàn)在,當(dāng)您的 PHP 程序讀回該字符時,一切似乎都正常工作,但數(shù)據(jù)庫實際上存儲的字符與您預(yù)期的不同。
您會注意到,只要您嘗試通過任何其他方式(例如在您的
psql
控制臺上)選擇該值。那里的值將呈現(xiàn)為locationY\u0086
這是如何使事情正常工作的解決方案:
創(chuàng)建一個帶有
UTF8
編碼的新數(shù)據(jù)庫。轉(zhuǎn)儲舊數(shù)據(jù)庫
pg_dump -F p -E LATIN1 dbname
手動編輯轉(zhuǎn)儲并更改行
SET client_encoding = 'LATIN1';
到
SET client_encoding = 'WIN1252';
將轉(zhuǎn)儲加載到新數(shù)據(jù)庫中
psql
。將
client_encoding
您的 PHP 應(yīng)用程序更改為WIN1252
并開始使用新數(shù)據(jù)庫。
- 1 回答
- 0 關(guān)注
- 560 瀏覽
添加回答
舉報