AngularJS+NodeJS+MySQL中Timestamp格式导致删除操作报错的问题
问题解析:MySQL不识别ISO 8601时间格式导致删除失败
嘿,这个问题我之前也碰到过,咱们一步步拆解原因和解决办法:
为什么会出现2018-02-10T14:19:29.000Z这种格式?
这其实是JSON序列化JavaScript Date对象的标准结果:
- 当你从MySQL查询
TIMESTAMP/DATETIME类型的字段时,NodeJS的MySQL驱动(比如mysql或mysql2)默认会把数据库返回的时间值转换成JavaScript的Date对象。 - 当你把这个
Date对象转成JSON(比如传给AngularJS客户端,或者直接用来构造SQL语句),JSON会自动将其序列化为ISO 8601格式的字符串,也就是带T(日期和时间分隔符)和Z(UTC时区标记)的格式。
为什么MySQL会报错?
MySQL的TIMESTAMP和DATETIME类型默认只识别不带特殊分隔符的时间格式,比如:
YYYY-MM-DD HH:MM:SS(标准格式)YYYY-MM-DD HH:MM:SS.ffffff(带毫秒的格式)
而2018-02-10T15:07:34.000Z里的T和Z属于MySQL无法解析的非法字符,所以它会抛出ER_TRUNCATED_WRONG_VALUE错误,认为你传入了不正确的datetime值。
解决办法(三种可选)
1. 在NodeJS层手动转换时间格式
把ISO格式的字符串转换成MySQL能识别的格式,原生JS或者日期库都能搞定:
// 原生JS实现 const isoTime = '2018-02-10T14:19:29.000Z'; const date = new Date(isoTime); // 拼接成YYYY-MM-DD HH:MM:SS格式 const mysqlTime = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}:${String(date.getSeconds()).padStart(2, '0')}`; // 用dayjs简化(推荐,更简洁不易出错) const dayjs = require('dayjs'); const mysqlTime = dayjs(isoTime).format('YYYY-MM-DD HH:mm:ss');
之后用mysqlTime作为删除语句的条件值即可。
2. 配置MySQL驱动,直接返回原始时间字符串
在创建数据库连接时,添加dateStrings: true配置,让驱动不再把时间转成Date对象,直接返回MySQL原生的时间格式:
const mysql = require('mysql'); const connection = mysql.createConnection({ host: '你的数据库地址', user: '用户名', password: '密码', database: '数据库名', dateStrings: true // 开启这个配置 });
这样查询到的instanceTime就是YYYY-MM-DD HH:MM:SS格式,直接用来删除就不会报错了。
3. 在SQL语句中用函数转换格式
用MySQL的STR_TO_DATE()函数,把ISO格式的字符串转换成数据库能识别的datetime类型:
DELETE FROM 你的表名 WHERE instanceTime = STR_TO_DATE('2018-02-10T14:19:29.000Z', '%Y-%m-%dT%H:%i:%s.%fZ') AND user_email = '用户邮箱';
这里的格式符%Y-%m-%dT%H:%i:%s.%fZ完全匹配ISO字符串的结构,%f用来解析毫秒部分。
内容的提问来源于stack exchange,提问作者lolu
相关产品推荐
相关产品推荐

