Как установить разделитель тысяч для PostgreSQL? - PullRequest
13 голосов
/ 29 июля 2010

Я хочу отформатировать длинные числа, используя разделитель тысяч. Это можно сделать с помощью функции to_char, например:

SELECT TO_CHAR(76543210.98, '999G999G990D00')

Но когда мой сервер PostgreSQL с кодировкой UTF-8 находится на польской версии Windows, такой SELECT заканчивается на:

ERROR:  invalid byte sequence for encoding "UTF8": 0xa0
HINT:  This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding".

В to_char шаблон G описывается как: разделитель групп (использует локаль) . Этот SELECT работает без ошибок, когда сервер работает в Linux с польским языком.

В качестве обходного пути я использую пробел вместо G в строке формата, но я думаю, что должен быть способ установить разделитель тысяч, как в Oracle:

ALTER SESSION SET NLS_NUMERIC_CHARACTERS=', ';

Доступна ли такая настройка для PostgreSQL?

Ответы [ 2 ]

15 голосов
/ 04 мая 2015

Если вы используете psql, вы можете выполнить это:

\pset numericlocale

Пример:

test=# create temporary table a (a numeric(20,10));
CREATE TABLE

test=# insert into a select random() * 1000000 from generate_series(1,3);
INSERT 0 3

test=# select * from a;
         a         
-------------------
 287421.6944910590
 140297.9311533270
 887215.3805568810
(3 rows)

test=# \pset numericlocale
Showing locale-adjusted numeric output.

test=# select * from a;
         a          
--------------------
 287.421,6944910590
 140.297,9311533270
 887.215,3805568810    
(3 rows)
3 голосов
/ 18 января 2011

Я почти уверен, что сообщение об ошибке буквально истинно: 0xa0 не является допустимым символом UTF-8.

Мой домашний сервер работает под управлением PostgreSQL в Windows XP, SP3.Я могу сделать это в psql.

sandbox=# show client_encoding;
 client_encoding
-----------------
 UTF8
(1 row)


sandbox=# show lc_numeric;
  lc_numeric
---------------
 polish_poland
(1 row)


sandbox=# SELECT TO_CHAR(76543210.98, '999G999G990D00');
     to_char
-----------------
   76 543 210,98
(1 row)

Я не получаю сообщение об ошибке, но я получаю мусор для разделителя.Может ли это быть проблемой кодовой страницы?

В качестве обходного пути я использую пробел вместо G в строке формата

Давайте подумаем об этом.Если вы используете пробел, то на веб-странице значение может разделиться в конце строки или на границе ячейки таблицы.Я думаю, что неразрывное пространство может быть лучшим выбором.

И в Unicode неразрывный пробел равен 0xa0.В Unicode, а не в UTF8.(То есть 0xa0 не может быть первым байтом символа UTF8. См. Распределение битов UTF-8 .)

Другая возможность состоит в том, что ваш клиент ожидает один порядок байтов, исервер дает ему другой порядок байтов.Поскольку числа являются однобайтовыми символами, порядок байтов не будет иметь значения, пока, ну, это не имеет значения.Если клиент ожидает символа с прямым порядком байтов MB, и он получил символ с прямым порядком байтов MB, начинающийся с 0xa0, я ожидаю, что он умрет с сообщением об ошибке, которое вы видели.Я не уверен, что у меня есть способ проверить это, прежде чем я пойду на работу сегодня.

...