to_char是oracle和部分postgresql版本支持的日期格式化函数,mysql和sql server不支持;需注意数据库兼容性、格式符含义(如mi为分钟、mm为月份)、双引号字面量、索引失效风险及nls设置影响。

TO_CHAR 日期格式化的基本用法和常见错误
Oracle 和 PostgreSQL(部分版本)支持 TO_CHAR,但 MySQL、SQL Server 完全不支持——直接执行会报错 ORA-00904: "TO_CHAR" invalid identifier 或类似提示。别急着改语法,先确认你连的是哪个数据库。Oracle 中它最稳定;PostgreSQL 需要 to_char(timestamp, text) 且第二个参数必须是字符串字面量,不能是变量或列。
典型写法是:TO_CHAR(sysdate, 'YYYY-MM-DD HH24:MI:SS')。注意大小写敏感:HH24 表示24小时制,HH12 是12小时制;MI 是分钟(不是 MM,那是月份);SS 是秒。写成 MM 在小时位置会导致结果错乱,比如把 14 点变成 “02” 月。
Oracle 中常用格式模型与易混淆项
格式模型不是正则,也不是任意拼写。比如想输出“2024年05月21日”,得写 'YYYY"年"MM"月"DD"日"'——双引号包裹的中文才是字面量,否则 年 会被当成非法格式符报错 ORA-01821: date format not recognized。
-
DAY返回完整英文星期名(如'TUESDAY'),带空格填充到9字符;要用缩写得用DY -
DD是每月第几天(1–31),D是每周第几天(1=Sunday),极易混用 - 世纪用
CC,年份用YYYY,但RR有特殊两位年份解释逻辑,生产环境建议一律用YYYY - 带前导零的小时用
HH24,不带零用FH24(F表示 fill mode off)
跨数据库兼容性替代方案
如果代码要兼顾 MySQL,别硬套 TO_CHAR。MySQL 用 DATE_FORMAT():DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s');SQL Server 用 FORMAT()(2012+)或 CONVERT():FORMAT(GETDATE(), 'yyyy-MM-dd HH:mm:ss')。三者格式符完全不同:%m vs MM vs MM(但 SQL Server 的 MM 是月份,mm 才是分钟)。
更稳妥的做法是:在应用层做格式化,SQL 只返回原始 TIMESTAMP 或 DATE 类型。尤其当字段参与索引查询时,TO_CHAR(date_col, 'YYYYMM') 会强制类型转换,导致无法走索引。
性能陷阱:别在 WHERE 或 JOIN 条件里用 TO_CHAR
写 WHERE TO_CHAR(create_time, 'YYYY-MM') = '2024-05' 看似方便,实际会让 create_time 列上的索引完全失效。Oracle 无法对函数结果建立索引(除非建函数索引,但维护成本高)。正确做法是用范围查询:
WHERE create_time >= DATE '2024-05-01' AND create_time <p>这个写法能命中索引,且不依赖 NLS 设置。另外,<code>TO_CHAR</code> 的输出受会话级 <code>NLS_DATE_FORMAT</code> 影响极小,但 <code>NLS_TERRITORY</code> 可能影响 AM/PM 显示,上线前务必在目标环境验证输出。</p>











