导读:本期聚焦于行者创作的《PostgreSQL数据类型格式化函数是什么?有什么用?常见误区一次讲清》,敬请观看详情。数据类型格式化函数是PostgreSQL中一类容易被忽视但非常实用的内置函数,核心包括to_char、to_date、to_number和to_timestamp四个。它们负责在字符串与数值、时间戳之间做双向转换,比如把数值1234.5格式化成1,234.50,或者把任意样式的日期字符串安全地解析成日期类型。许多开发者在写报表SQL、处理多语言地区格式、解析非标准导入数据时都会用到它们。本文将从函数的基本作用讲起,逐一演示格式化模板的写法,再对齐Oracle迁移场景下的行为差异,最后总结几个高频踩坑点,例如FM填充模式、TH序数后缀与to_number的对应关系,帮助你写出更健壮的转换SQL。

在PostgreSQL中做数据转换时,很多人习惯直接用cast做类型强转,但一旦涉及千分位、货币符号、自定义日期样式这类需求,cast就无能为力了。PostgreSQL专门提供了一组数据类型格式化函数,包括to_charto_dateto_numberto_timestamp,它们通过模板字符串精确控制输入输出的格式,是报表输出、异构数据导入、Oracle系统迁移等场景的利器。本文将系统讲解这组函数的用法、模板语法以及常见的误区。

PostgreSQL数据类型格式化函数是什么?有什么用?常见误区一次讲清

一、格式化函数家族有哪些,各自负责什么

PostgreSQL的格式化函数一共有四个,功能上两两对应:to_char负责把数值或时间戳转成字符串,to_number负责把字符串解析成数值,to_date负责把字符串解析成日期,to_timestamp负责把字符串解析成时间戳。它们都接收两个参数:待转换的数据和格式模板。

to_char是最常用的一个。对数值类型,它可以控制小数位数、千分位、货币符号和负号位置;对时间类型,它可以输出几乎任意样式的日期时间文本,例如:

-- 数值格式化
SELECT to_char(1234567.891, 'FM999,999,990.00');  -- 结果:1,234,567.89

-- 时间格式化
SELECT to_char(now(), 'YYYY-MM-DD HH24:MI:SS');   -- 结果:2024-06-15 14:30:05
SELECT to_char(now(), 'YYYY"年"MM"月"DD"日"');      -- 结果:2024年06月15日

to_numberto_date则是反方向的解析。在处理从Excel或CSV导入的脏数据时,它们比cast安全得多,因为cast遇到带逗号的数字或非标准日期会直接报错,而格式化函数只要模板匹配就能正确解析:

SELECT to_number('1,234,567.89', '9G999G999D99');  -- 结果:1234567.89
SELECT to_date('2024/06/15', 'YYYY/MM/DD');         -- 结果:2024-06-15
SELECT to_timestamp('2024-06-15 14:30:05', 'YYYY-MM-DD HH24:MI:SS');

需要说明的是,模板中的9表示一个数字位,G代表分组分隔符(通常是逗号),D代表小数点,MI表示负号位置。这些模板修饰符是理解整组函数的关键。

二、格式模板的常用修饰符与使用技巧

时间格式模板是最丰富的部分。常用的有YYYY(四位年份)、YY(两位年份)、MM(月份)、DD(日)、HH24(24小时制)、HH12(12小时制)、MI(分钟)、SS(秒)、MS(毫秒)、US(微秒)、AM或PM(上下午标识)、Day(星期的完整英文名)以及Month(月份英文名)等。搭配引号可以嵌入固定文字,例如'YYYY"年第"Q"季度"'中的Q会输出季度数字。

数值模板方面,0和9的区别值得注意:9表示有数字才占位,0表示强制占位。比如to_char(42, '00099')输出00042,而to_char(42, '99999')输出42(前面留空)。这在需要对齐报表数字列时特别有用。另外还有L(本地货币符号,如人民币符号)、MI(负号放右侧或标出位置)、S(强制符号)、RN(罗马数字)、TH或th(序数后缀,如4TH)等修饰符。

SELECT to_char(42, 'FM00000');        -- 00042,强制补零
SELECT to_char(42, 'FM00th');         -- 42nd,序数后缀
SELECT to_char(1234.5, 'FML999G990.00'); -- 人民币符号加千分位
SELECT to_char(now(), 'Day, DD Month YYYY');

还有一个实用技巧:模板中两个连续的单引号表示一个字面单引号,而用双引号包裹的内容会被当作普通文本原样输出,不被解析为模板模式。掌握这两条规则,基本可以拼出任何想要的输出样式。

三、与Oracle的差异以及常见的踩坑点

很多从Oracle迁移过来的项目会大量使用这组函数,因为函数名和大部分模板语法都一致。但PostgreSQL在细节上与Oracle不同,这也是最容易踩坑的地方。

第一个坑是FM填充模式。to_char默认会在输出前补空格占位,比如to_char(42, '999')的结果是空格加42,占三个字符宽度。如果不想要这些填充空格,需要在模板前加FM前缀。而更隐蔽的是to_number方向:如果解析时模板里没有FM,带前导空格的字符串可能解析异常。建议在双向转换时保持模板风格一致。

第二个坑是to_date的宽容性带来的脏数据风险。PostgreSQL对某些不严格的输入会尝试容错,例如年份只给两位时按一定的规则补全,这在生产环境解析用户输入时可能产生意料之外的日期。更稳妥的做法是先校验格式再转换,或者用to_timestamp配合异常处理。

第三个坑是L、G、D这类修饰符受地区设置影响。L对应的货币符号、G对应的分组符会随服务器或会话的LC_NUMERIC设置变化。如果系统要输出固定格式(比如对接固定宽度的对账文件),不要依赖这些修饰符,改用字面量的逗号和句点更可靠:

-- 更可控的写法:不用G和D,直接写死分隔符
SELECT to_number('1,234,567.89', '9,999,999.99');

第四个坑是性能。格式化函数的解析成本高于直接cast,在大批量ETL场景中,如果源数据格式本身就是标准的ISO样式,直接用::numeric::timestamp转换会快很多,只在格式不规则时才动用模板函数。

总结一下,这四个格式化函数的核心价值在于精确可控的双向转换:输出时用于报表和展示,输入时用于解析脏数据。使用时记住三条原则——模板修饰符与地区设置解耦、FM模式双向一致、大批量场景优先用cast,就能避开绝大多数问题。

PostgreSQL格式化函数to_char修改时间:2026-09-02 23:45:05

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260902/49210.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。