STR_TO_DATE()是MySQL中唯一严格按模板解析字符串为日期的函数,逐字符匹配失败即返回NULL且不报错;多格式需用CASE WHEN分支判断,LOAD DATA需配合用户变量和NULLIF处理。

STR_TO_DATE() 是 MySQL 中唯一能按模板硬解析字符串为日期的函数,其他如 DATE()、CAST() 在非标准格式下基本失效,且不报错——直接返回 NULL 或 0000-00-00,极易漏检。
为什么 STR_TO_DATE 会静默返回 NULL
它不是“尽力而为”的转换器,而是逐字符严格匹配的解析器。只要字符串和格式串在任意位置存在偏差(空格、大小写、分隔符、前导零、月份缩写大小写、甚至中文字符),就立刻返回 NULL,且不抛任何警告或错误。
- 输入
'2023-5-1'却用'%Y-%m-%d'→ 失败(5不是05) - 输入
'15/Mar/2023'却用'%d/%M/%Y'→ 失败(%M要求March,%b才认Mar) - 输入
'2023年05月12日'却用'%Y-%m-%d'→ 失败(中文字符必须原样写进格式串:'%Y年%m月%d日') - 输入
'2023-05-12T14:30:00'却漏掉T→ 格式串必须是'%Y-%m-%dT%H:%i:%s'
多格式混杂时必须用 CASE WHEN 分支处理
现实数据常混着 '2023/05/12'、'12.05.2023'、'May 12, 2023' 等多种格式,单靠一个 STR_TO_DATE() 调用无法覆盖。
- 每个
WHEN分支必须用STR_TO_DATE(col, fmt) IS NOT NULL判断是否成功,不能只靠正则或长度猜格式 - 把最常见格式放前面,避免低频格式误触发高优先级分支
- 示例:
CASE WHEN STR_TO_DATE(str_col, '%Y/%m/%d') IS NOT NULL THEN STR_TO_DATE(str_col, '%Y/%m/%d') WHEN STR_TO_DATE(str_col, '%d.%m.%Y') IS NOT NULL THEN STR_TO_DATE(str_col, '%d.%m.%Y') END - 千万别让
CASE最后兜底为0000-00-00—— 应该留ELSE NULL,再单独查出这些NULL记录人工核对
在 LOAD DATA INFILE 中使用 STR_TO_DATE 的关键写法
不能在字段列表里直接写函数,必须通过用户变量 + SET 子句完成转换,否则语法报错。
- 必须先声明变量接收原始值:
@date_str - 必须显式初始化防污染:
@date_str := NULLIF(@date_str, '') - 正确写法:
SET created_at = STR_TO_DATE(@date_str := NULLIF(@date_str, ''), '%Y-%m-%d') - 如果源数据含时间(如
'2023-05-12 14:30'),目标列为DATETIME,格式串就得补全:'%Y-%m-%d %H:%i';否则存成2023-05-12 00:00:00
真正难的不是记格式符,而是那些看不见的干扰:不可见空格、BOM头、大小写不一致、MySQL 当前 sql_mode 是否开启 ALLOW_INVALID_DATES——它会让 '2023-02-30' 这种非法日期也解析成功。上线前务必用真实数据样本跑 SELECT str_col, STR_TO_DATE(str_col, fmt) FROM t LIMIT 100 验证,别等批量更新完才发现半数是 NULL。


















