STR_TO_DATE()返回NULL说明格式模板与输入字符串未逐字符匹配,而非函数或数据故障;必须严格按分隔符、顺序、大小写等一一对应,如'2024/03/15'需'%Y/%m/%d','15-Mar-2024'需'%d-%b-%Y'。

STR_TO_DATE() 返回 NULL 就是格式模板没对上,不是函数坏了,也不是数据有问题。
STR_TO_DATE() 格式模板必须和输入字符串逐字符匹配
MySQL 不会“猜”你写的日期是什么格式。它只按你给的 %Y、%m、%d 等占位符去硬匹配输入字符串的结构。哪怕分隔符差一个字符(比如 / 写成 -),或者顺序错一位(%Y-%m-%d 传了 '15-03-2024'),STR_TO_DATE() 就返回 NULL,悄无声息。
- 输入是
'2024/03/15'→ 模板必须是'%Y/%m/%d',不是'%Y-%m-%d' - 输入是
'15-Mar-2024'→ 模板得用'%d-%b-%Y',%b才认英文缩写 - 输入带时间且是 12 小时制,比如
'03/15/2024 02:30 PM'→ 模板要写'%m/%d/%Y %I:%i %p',%I和%p缺一不可
INSERT 时直接写标准格式比套函数更稳
如果能控制上游数据格式,优先让应用层或前端输出 'YYYY-MM-DD' 或 'YYYY-MM-DD HH:MM:SS'。这种格式 MySQL 原生识别,不依赖 STR_TO_DATE(),也不怕模板写错。
-
DATE字段:直接插'2024-08-10' -
DATETIME字段:直接插'2024-08-10 14:22:30' - 避免在 SQL 里拼接变量,尤其别用 PHP 的
"' . $date . '"这种方式——容易引号错位、SQL 注入,还掩盖了格式问题
遇到 Incorrect datetime value 错误先查三件事
这个错误不是格式不对那么简单,它往往意味着值本身非法,或者 SQL Mode 太严。
- 执行
SELECT @@sql_mode;看是否启用了STRICT_TRANS_TABLES—— 开着就拒绝任何模糊或非法值 - 检查日期是否真实存在:比如
'2024-02-30'、'2024-13-01'、'0000-00-00'都会被拒 - 确认字段类型允许的范围:
DATE是'1000-01-01'到'9999-12-31',超限也会报错
导入 CSV 或 LOAD DATA 时日期变 0000-00-00
这通常不是数据错了,而是导入工具(如 phpMyAdmin、MySQL Workbench)没配对日期格式,导致 MySQL 按默认规则解析失败后填零。
- 在导入向导里找 “Date format” 或 “DateTime format” 设置项,手动选成和文件里一致的格式,比如
Y-m-d、m/d/Y - 如果文件里是
'2024.08.10',就得设成Y.m.d,不能指望 MySQL 自动识别点号 - 导入前用
SELECT STR_TO_DATE('2024.08.10', '%Y.%m.%d');测试下能否成功解析,再批量操作
最麻烦的不是不会写模板,而是模板写对了,但数据里混进了空字符串、全零日期、或前端传来的非法时间戳。上线前拿真实样本跑一遍 STR_TO_DATE() 测试,比事后查 NULL 值快得多。


















