You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 12:24:08