是否可以在 PostgreSQL 中为货币数据类型插入未格式化的数据

Ram*_*ini 5 postgresql datatypes money

默认情况下,PostgreSQL 的money数据类型插入带有货币代码和分组的值。我观察到它总是用$.

  1. 如何插入特定于语言环境的值?
  2. 如何使用我自己的数字分组和十进制分组格式插入值?
  3. 如何读取未格式化的数据?
  4. 为什么 PostgreSQL 的货币数据类型与 MS SQL 的货币数据类型不同?

Erw*_*ter 7

  1. 如何插入特定于语言环境的值?

相应地设置LC_MONETARY。(仅影响money格式化输出中的类型和一些货币细节!)您可以将其作为整个数据库集群的永久默认设置postgresql.conf,仅用于当前会话SET或仅用于事务SET LOCAL。(或以其他几种方式。

在 Windows 机器上演示:

BEGIN;
CREATE TEMP TABLE mdemo(id serial, m money);

SET LOCAL lc_monetary = 'German_Austria.1252';
INSERT INTO mdemo(m) VALUES ('123.45');

SET LOCAL lc_monetary = 'English_US.1252';
INSERT INTO mdemo(m) VALUES ('123.45');
TABLE mdemo;

 id |     m
----+------------
  1 | $12,345.00
  2 |    $123.45


ROLLBACK;  -- to clean up
Run Code Online (Sandbox Code Playgroud)

如您所见,字符串文字 '123.45' 是根据LC_MONETARY. 在奥地利,点 ( .) 用作组分隔符并且,是小数点。而在美国,情况正好相反。

找到正确的语言环境名称很重要。手册:

您的系统上以什么名称提供的语言环境取决于操作系统供应商提供的内容以及安装的内容。在大多数 Unix 系统上,该命令locale -a将提供可用语言环境的列表。Windows 使用更详细的语言环境名称,例如German_Germanyor Swedish_Sweden.1252,但原理是相同的。


  1. 如何使用我自己的数字分组和十进制分组格式插入值?

用于从字符串文字中to_number()生成一个numeric值,该值又可以转换为money.

说,你有这个文字::'12,454.8-'2 位数字,,作为组分隔符,3 位数字,.作为小数点,1 位数字,待定符号。这不起作用:

SELECT money '12,454.8-';
Run Code Online (Sandbox Code Playgroud)

作品:

SELECT to_number('12,454.8-', '99,999.9S')::money
Run Code Online (Sandbox Code Playgroud)

由于我们正在阅读一般数字,因此更一般的设置LC_NUMERIC适用于导入,而设置LC_MONETARY仍然决定了结果的显示方式!从numericto 的转换money与语言环境无关(不可变)。不要混淆。

第二个参数中的模式也很棘手。像,.这样的符号按字面意思理解并根据 C 语言环境(无语言环境)进行解释,而模式(您也可以使用'99G999D9S')根据当前语言环境进行解释。

我建议澄清 pgsql-docs 的手册。


  1. 如何读取未格式化的数据?

您可以阅读它,但是如果没有关于其格式的最少信息,您几乎无法将其转换为任何数字类型。


我还是宁愿不使用数据类型money。狭隘、古怪的规格。使用numeric覆盖所有基地。或者只是integer表示美分,表现更好。看: