如何在Node.js的MySQL自定义查询中使用MomentJS处理日期参数
问题修复方案
报错原因
你触发语法错误的核心原因是:动态拼接SQL时没有给日期字符串参数添加单引号包裹,MySQL无法识别未包裹的日期文本为合法的日期类型参数。
你当前代码插值后生成的WHERE子句实际效果为:
WHERE seg.segment_departure_date BETWEEN 2021-10-01 00:00:00 AND 2021-10-31 23:59:59
MySQL会把2021-10-01识别为数值运算(2021减10减1),后续的时间戳文本完全不符合语法规则,直接触发解析错误。
修复方法
方法1:快速修复(直接加单引号)
给插值的两个日期参数两侧添加单引号即可解决语法报错,修改后的代码如下:
date_count = await customQuery( ` SELECT COUNT(org.name OR c.name OR co.name OR seg.arrival_details OR seg.departure_details OR seg.segment_airline_id OR seg.segment_arrival_airport_code OR seg.segment_departure_airport_code OR seg.segment_flight_number OR seg.trip_id OR b.trip_id OR bf.pnr_no OR bf.airline_pnr_no OR b.booking_status OR b.created OR org.organisation_id OR org.name ) AS total_count FROM segment_details AS seg LEFT JOIN trip_details AS tr ON seg.trip_id = tr.trip_id LEFT JOIN bookings_flight AS bf ON tr.bookings_flight_id = bf.booking_flight_id LEFT JOIN bookings AS b ON bf.booking_id = b.booking_id LEFT JOIN organisation AS org ON b.organisation_id = org.organisation_id LEFT JOIN city AS c ON org.city_id = c.city_id LEFT JOIN country AS co ON org.country_id = co.country_id WHERE seg.segment_departure_date BETWEEN '${moment(date.startDate).startOf('day').format("YYYY-MM-DD HH:mm:ss")}' AND '${moment(date.endDate).endOf('day').format("YYYY-MM-DD HH:mm:ss")}' `)
方法2:更安全的参数化查询(推荐)
直接拼接SQL存在SQL注入风险,建议你使用参数化查询方式传参,不同的数据库驱动参数占位符略有区别,示例写法如下:
// 示例:使用?作为占位符,参数按顺序传入 date_count = await customQuery( ` SELECT COUNT(*) AS total_count FROM segment_details AS seg LEFT JOIN trip_details AS tr ON seg.trip_id = tr.trip_id LEFT JOIN bookings_flight AS bf ON tr.bookings_flight_id = bf.booking_flight_id LEFT JOIN bookings AS b ON bf.booking_id = b.booking_id LEFT JOIN organisation AS org ON b.organisation_id = org.organisation_id LEFT JOIN city AS c ON org.city_id = c.city_id LEFT JOIN country AS co ON org.country_id = co.country_id WHERE seg.segment_departure_date BETWEEN ? AND ? `, [ moment(date.startDate).startOf('day').format("YYYY-MM-DD HH:mm:ss"), moment(date.endDate).endOf('day').format("YYYY-MM-DD HH:mm:ss") ] )
额外优化建议
你当前COUNT中写的多字段OR逻辑,等价于统计所有满足「任意一个字段不为NULL」的行数,和COUNT(*)效果完全一致,可以直接替换为COUNT(*)简化语句,提升执行效率。
另外注意你原始日期是UTC格式(带Z后缀),如果你的数据库存储的是本地时区时间,需要确保MomentJS转换时区和数据库时区一致,避免查询结果不符合预期。
内容的提问来源于stack exchange,提问作者zaid
相关产品推荐
相关产品推荐

