【问题标题】:How to set thousand separator for PostgreSQL?如何为 PostgreSQL 设置千位分隔符?
【发布时间】:2010-07-29 08:47:09
【问题描述】:

我想使用千位分隔符格式化长数字。可以使用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 可以使用这样的设置吗?

【问题讨论】:

    标签: postgresql formatting locale


    【解决方案1】:

    如果你使用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)
    

    【讨论】:

    • 要永久执行此操作,请将\pset numericlocale 放入~/.psqlrc
    • 要关闭它,请使用:\pset numericlocale off
    【解决方案2】:

    我很确定错误消息是真的: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 字符,我希望它会因您看到的错误消息而死。我不确定我今天上班前有没有办法对此进行测试。

    【讨论】:

    • 你是对的,你可能用 PostgreSQL 9.0.2 测试过它,我用 9.0.1 测试过它,它可以工作,但在控制台上显示“垃圾”。使用 JDBC 或 ODBC 客户端它可以在没有垃圾的情况下工作,所以我认为它是 PostgreSQL 中的错误,已修复。但问题:“我可以设置临时千位分隔符吗?”没有回答。可能不在 PostgreSQL 的实际版本中。
    • @Michal Niklas:见我上面的编辑。我不确定它的重要性。
    • 谢谢。我的客户端可以正常工作一段时间(psql 在控制台上显示垃圾,因为控制台使用 CP852)。新版本的 PostgreSQL 解决了 select 的问题。但即使使用 9.0.2,当我想导入带点的 CSV 文件时,我也不知道如何将千位分隔符设置为点,然后当其他客户向我发送带逗号的文件时,如何将千位分隔符设置为逗号。现在我必须使用 Python/Perl 等转换此类文件。使用 Oracle,我可以设置一些会话变量,然后数据库对其进行转换。
    • 如果您可以在桌面上运行 PostgreSQL,您可能可以解决这个问题。您可以更改 postgresql.conf 中的本地化设置并重新启动服务器。首先将数据导入您的桌面,然后将其推送到公司的服务器。 (有人告诉我,LC_NUMERIC 也给 Oracle 带来了很多麻烦。)
    猜你喜欢
    • 1970-01-01
    • 2011-07-16
    • 1970-01-01
    • 2016-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多