to_char и кодировки

Изображение msi

Мне непонятно зависимость поведения to_char при форматировании даты от кодировки.
При кодировке
ENCODING = 'LATIN1'
запрос
select to_char(current_timestamp, 'HH:MI')
валится с ошибкой:
ERROR: character 0xd092 of encoding "UTF8" has no equivalent in "LATIN1"

При кодировке ENCODING = 'UTF8' отрабатывает нормально.

Просьба объяснить такое поведение или дать ссылку на мануал.
Ну, и сопутствующий вопрос. Как изменить кодировку существующей базы данных?

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

А как current_timestamp

А как current_timestamp выглядит?
Судя по ситуации, которую вы описали, попался символ которого нет в наборе LATIN1 (например русская буква), вот собственно и ошибка.

Current_timestamp

Изображение msi

Current_timestamp взят для простоты. Это роли не играет.
Вот другой пример с той же ошибкой:

select cast('2011-12-05T13:49:00' as timestamp);
"2011-12-05 13:49:00"
select to_char(cast('2011-12-05T13:49:00' as timestamp), 'HH:MI')

Проверить можно здесь

Изображение msi

Проверить можно здесь (выбрать PGSQL и поставить флажок "без проверки").

Чего-то не пойму: # set

Чего-то не пойму:

# set CLIENT_ENCODING TO 'LATIN1';
SET
# select to_char(cast('2011-12-05T13:49:00' as timestamp), 'HH:MI');
 to_char 
---------
 01:49
(1 row)
# set CLIENT_ENCODING TO 'UTF-8';
SET
# select to_char(cast('2011-12-05T13:49:00' as timestamp), 'HH:MI');
 to_char 
---------
 01:49
(1 row)

Что не так делаю?

Так и должно быть, на мой

Изображение msi

Так и должно быть, на мой взгляд.
Но почему у нас не работает с кодировкой LATIN1? В этом и вопрос.
Может быть есть разница между кодировкой на сервере и на клиенте?

Кодировка на сервере всегда

Кодировка на сервере всегда ОДНА, её нельзя переключить и соответствует она, либо той кодировке, которую задали при инициализации кластера баз данных, либо той, которую задали при создании конкретной БД. А вот кодировки на клиенте можно переключать, но цель этого переключения - обеспечить правильное ОТОБРАЖЕНИЕ данных, предоставляемых сервером. Т.е. если у вас сервер в UTF-8, то клиент должен быть в той кодировке, которая у вас настроена для клиента, например для Windows и консоли в cp866, для приложений в cp1251 иначе русских букв не увидеть будет.

Так уж получилось, что у нас

Изображение msi

Так уж получилось, что у нас при создании двух баз получились разные кодировки.
Я, конечно, могу пересоздать базу с другой кодировкой, но хотелось бы разобраться в проблеме.

А мне бы для начала хотелось

А мне бы для начала хотелось эту проблему увидеть. Но я не понимаю как?

Вот все параметры базы:

Изображение msi

Вот все параметры базы:

ENCODING = 'LATIN1'
TABLESPACE = pg_default
LC_COLLATE = 'C'
LC_CTYPE = 'C'

Могу прислать дамп.

Изображение msi

Могу прислать дамп.

Давайте попробуем

Давайте попробуем

Не нашел адреса. Куда

Изображение msi

Не нашел адреса.
Куда отправить?

Да просто сделать архивчик,

Да просто сделать архивчик, скинуть на публичный файлообменник и ссылку сюда. Так будет проще всего.

OK

Изображение msi

Что делаю не так?

#su - postgres
$ createdb comp
$ pg_restore -d comp /tmp/compDB_PG.backup
$ psql comp
comp=# \dt
            List of relations
 Schema |     Name     | Type  |  Owner   
--------+--------------+-------+----------
 public | battles      | table | postgres
 public | classes      | table | postgres
 public | company      | table | postgres
 public | income       | table | postgres
 public | income_o     | table | postgres
 public | laptop       | table | postgres
 public | outcome      | table | postgres
 public | outcome_o    | table | postgres
 public | outcomes     | table | postgres
 public | pass_in_trip | table | postgres
 public | passenger    | table | postgres
 public | pc           | table | postgres
 public | printer      | table | postgres
 public | product      | table | postgres
 public | ships        | table | postgres
 public | trip         | table | postgres
 public | utb          | table | postgres
 public | utq          | table | postgres
 public | utv          | table | postgres
(19 rows)

comp=# select to_char(current_timestamp, 'HH:MI');
to_char
---------
11:30
(1 row)

Никаких сообщений об ошибках не наблюдается

Может у вас версия какая-то левая?

У меня: postgresql-9.0.5-1


Может и левая, но, скорее

Изображение msi

Может и левая, но, скорее всего, официальная:
PostgreSQL 9.0.4, compiled by Visual C++ build 1500, 64-bit
Как, кстати, переименовать базу?

> Как, кстати, переименовать

> Как, кстати, переименовать базу?
ALTER DATABASE name RENAME TO new_name

> Может и левая, но, скорее всего, официальная:
Может в платформе дело? Я на Linux

> Может в платформе дело? Я

Изображение msi

> Может в платформе дело? Я на Linux

Возможно. А пока попробую развернуть из бэкап в другую базу.

Как отключить пользователей

Изображение msi

Как отключить пользователей от базы, чтобы ее переименовать?

set CLIENT_ENCODING TO

Изображение msi

set CLIENT_ENCODING TO 'UTF8';

ничего не изменил (PgAdmin III). Та же ошибка.
Может быть сочетание параметров играет роль?

А если выкинуть нафиг

А если выкинуть нафиг pgAdminIII и попробовать в psql?
Просто pgAdmin кривоподелие ещё то, которое может свои собственные параметры на сессию ставить и никому о них не говорить.

> А если выкинуть нафиг

Изображение msi

> А если выкинуть нафиг pgAdminIII и попробовать в psql?

Так я на сайте вижу то же самое, что и в pgAdmin. Так что дело не в нем.
Но попробовал. Ошибка та же. Но было еще предупреждение:
WARNING: Console code page (866) differs from Windows code page (1251)
8-bit characters might not work correctly. See psql reference
page "Notes for Windows users" for details.
Может это повлиять? Впрочем, на базе с другой кодировкой выдается то же предупреждение.

Предупреждение говорит, что в

Предупреждение говорит, что в консоли кодировка cp866 а не cp1251 как обычно в винде. Обычно ставится при это SET CLIENT_ENCODING TO 'CP866'; и всё ок. В общем я не знаю как вашу ошибку воспроизвести:
# su - postgres
$ createdb -l C -E LATIN1 -T template0 tmp1
$ psql tmp1
tmp1=# select to_char(cast('2011-12-05T13:49:00' as timestamp), 'HH:MI');
 to_char 
---------
 01:49
(1 row)
даже на всякий случай сделал: tmp1=# select * from pg_database where datname='tmp1';
datname datdba encoding datcollate datctype datistemplate datallowconn datconnlimit datlastsysoid datfrozenxid dattablespace datconfig datacl
tmp1 10 8 C C f t -1 11563 648 1663    

(1 row)

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Back to top

(С) Виктор Вислобоков, 2008-2023