TO_CHAR日期转字符串必须显式指定格式模型,否则依赖NLS_DATE_FORMAT导致结果不可控;分钟必须用MI而非MM;GROUP BY日期需先格式化;NULL处理需配合NVL/COALESCE;避免TO_CHAR结果再TO_DATE回转。

TO_CHAR 日期转字符串必须指定格式模型
不加格式参数的 TO_CHAR(date_col) 会依赖数据库 NLS_DATE_FORMAT 设置,结果不可控。比如在某些环境返回 27-DEC-23,另一些环境可能是 2023-12-27,报表或接口对接时极易出错。
正确做法是显式传入格式模型:
-
TO_CHAR(hire_date, 'YYYY-MM-DD')→2023-12-27 -
TO_CHAR(hire_date, 'YYYY"年"MM"月"DD"日"')→2023年12月27日(双引号内字符原样输出) -
TO_CHAR(hire_date, 'FMMM/FMDD/YYYY')→ 去掉前导零,如4/5/2023(FM是填充掩码,避免空格或 0)
hh24:mi:ss 和 hh24:mm:ss 是常见拼写错误
Oracle 里分钟必须用 mi,不是 mm——mm 永远代表月份。写成 'hh24:mm:ss' 会导致 ORA-01810:format code appears twice 错误,因为 mm 已在前面被解释为“月”,后面又出现一次。
典型错误与修正:
- ❌
TO_CHAR(sysdate, 'HH24:MM:SS')→ 报错 - ✅
TO_CHAR(sysdate, 'HH24:MI:SS')→ 正确(MI是分钟,大小写不敏感但建议大写) - ✅
TO_CHAR(sysdate, 'HH12:MI:SS AM')→ 12 小时制带上午/下午标识
按年月分组统计时别直接 GROUP BY DATE 字段
DATE 类型字段实际包含时分秒。如果直接 GROUP BY order_date,哪怕同一天的两条记录时间分别是 2023-01-01 10:00:00 和 2023-01-01 15:30:00,也会被当成不同值,无法合并统计。
应先格式化再分组:
SELECT TO_CHAR(order_date, 'YYYY-MM') AS ym, COUNT(*) FROM orders GROUP BY TO_CHAR(order_date, 'YYYY-MM')- 更高效写法(避免两次计算):
SELECT ym, COUNT(*) FROM (SELECT TO_CHAR(order_date, 'YYYY-MM') AS ym FROM orders) GROUP BY ym - 注意:不能用
TO_CHAR(order_date, 'YYYYMM')当数字用——它返回字符串,参与数值运算会隐式转换,可能引发 NLS 问题
TO_CHAR 处理 NULL 日期要小心
TO_CHAR(NULL, 'YYYY-MM-DD') 结果就是 NULL,不会报错,但容易在前端展示为空白,业务方误以为数据缺失。若需默认值,得配合 NVL 或 COALESCE:
-
TO_CHAR(NVL(birth_date, DATE '1900-01-01'), 'YYYY-MM-DD')→ 把空生日转成固定占位符 -
COALESCE(TO_CHAR(expire_date, 'YYYY-MM-DD'), '永久有效')→ 空则显示中文提示 - 切记:不要对
TO_CHAR的结果再套TO_DATE回转——除非你确定格式完全一致,否则极易因空格、大小写、语言环境导致 ORA-01843 或 ORA-01858
DUAL 上验证一遍输出,再嵌入正式 SQL。


















