我想使用千位分隔符格式化长数字。它可以使用to_char
函数完成,如:
SELECT TO_CHAR(76543210.98, '999G999G990D00')
但是当我使用UTF-8编码的PostgreSQL服务器在波兰语版本的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
被描述为:组分隔符(使用区域设置)。
当服务器在具有波兰语语言环境的Linux上运行时,此SELECT可以正常运行。
作为一种解决方法,我在格式字符串中使用空格而不是G
,但我认为应该像在Oracle中一样设置千位分隔符:
ALTER SESSION SET NLS_NUMERIC_CHARACTERS=', ';
这样的设置是否适用于PostgreSQL?
答案 0 :(得分:14)
如果您使用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)
答案 1 :(得分:3)
我很确定错误消息确实是真的:0xa0不是有效的UTF-8字符。
我的家庭服务器在Windows XP,SP3上运行PostgreSQL。我可以在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 Bit Distribution。)
另一种可能性是您的客户端期望一个字节顺序,并且服务器给它一个不同的字节顺序。由于数字是单字节字符,因此字节顺序无关紧要,直到它才重要。如果客户端期望一个大端的MB字符,并且它有一个以0xa0开头的小字节MB字符,我希望它会因你看到的错误信息而死掉。在我今天上班之前,我不确定我是否有办法测试这个。