TO_DATE是Oracle专用函数,用于将字符串按指定格式(如'YYYY-MM-DD')显式转换为DATE类型;格式必须严格匹配,否则报ORA-01861等错误,且不适用于MySQL等其他数据库。

TO_DATE在Oracle中怎么用?
TO_DATE只存在于Oracle,其他数据库(MySQL、PostgreSQL、SQL Server)没有这个函数。如果你在非Oracle环境里搜到这个函数名,大概率是文档看错了,或者正在迁移SQL脚本。
它的核心作用是把字符串按指定格式解析成Oracle的DATE类型值。格式字符串不是随便写的,必须和输入字符串严格匹配,否则直接报错:ORA-01861: literal does not match format string。
- 基本写法:
TO_DATE('2024-03-15', 'YYYY-MM-DD') - 月份用
MM,不是mm(小写mm是分钟) - 年份用
YYYY,YY会导致2000年问题(比如'01'可能被当成2001或1901) - 中文日期如
'2024年3月15日'要写成TO_DATE('2024年3月15日', 'YYYY"年"MM"月"DD"日"'),引号包裹字面量
为什么TO_DATE总报ORA-01843错误?
ORA-01843: not a valid month是最常见的报错,根本原因是格式模型里的月份部分和实际字符串对不上——比如用MM去解析'Mar',或用MON去解析'03'。
-
MM:两位数字月份(01–12) -
MON:英文缩写(JAN、FEB…),受数据库NLS_DATE_LANGUAGE影响,中文环境可能不认'MAR' -
MONTH:英文全称,同样依赖NLS设置 - 稳妥做法:统一用数字格式,避免语言依赖;如果必须用英文缩写,显式指定会话语言:
ALTER SESSION SET NLS_DATE_LANGUAGE = 'AMERICAN'
TO_DATE和隐式转换的区别在哪?
Oracle允许把字符串直接当DATE用(比如WHERE order_date > '2024-03-15'),但这依赖隐式转换,背后实际调用了TO_DATE,且使用的是会话级默认格式NLS_DATE_FORMAT。一旦会话格式和字符串不一致,就出错。
- 隐式转换不可控,不同环境结果可能不同
- 显式写
TO_DATE('2024-03-15', 'YYYY-MM-DD')能确保行为一致 - 性能上没差别——Oracle内部都会走同样的解析逻辑
- 唯一例外:索引字段如果是DATE类型,而你用
TO_DATE包裹列(如TO_DATE(order_date)),会导致索引失效;但这是对列用函数,不是对字符串用
其他数据库怎么替代TO_DATE?
别硬套名字。各数据库有各自的标准函数:
- MySQL:
STR_TO_DATE('2024-03-15', '%Y-%m-%d')或CAST('2024-03-15' AS DATE) - PostgreSQL:
TO_DATE('2024-03-15', 'YYYY-MM-DD')(注意:这函数存在但返回DATE而非TIMESTAMP;更常用CAST('2024-03-15' AS DATE)) - SQL Server:
CONVERT(DATE, '2024-03-15')或TRY_CONVERT(DATE, '2024-03-15')(后者失败不报错) - SQLite:
DATE('2024-03-15')
跨数据库写SQL时,最安全的是用标准SQL的CAST,但要注意各数据库对字符串格式的容忍度差异——比如CAST('15/03/2024' AS DATE)在PostgreSQL里可能失败,而在SQL Server里能认。

















