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

MySQL导入CSV时无效日期报错,触发器无法捕获问题求助

解决LOAD DATA导入无效日期时触发器无法捕获错误的问题

问题核心

你遇到的问题本质是MySQL的字段类型校验优先级高于触发器执行:当脏表的fecha_fallo_notificacion字段是DATE类型时,LOAD DATA导入过程中,MySQL会先校验日期格式的合法性,遇到2023-09-31这类无效日期时,直接抛出1292错误并终止插入操作,此时BEFORE/AFTER INSERT触发器根本没有执行的机会,自然无法将错误信息写入errores_carga表。

另外你提供的触发器代码存在两个问题:

  1. 触发器名称与关联表名重复(dirty_si_base_AFTER_INSERT既是触发器名又是表名),属于语法错误;
  2. 用STR_TO_DATE(...) IS NOT NULL判断日期有效性的逻辑不成立——遇到无效日期时,STR_TO_DATE会直接抛出1292错误,而非返回NULL,导致判断代码无法执行。

解决方案

步骤1:修改脏表的日期字段类型

将DATE类型改为VARCHAR(10),绕过MySQL的前置日期校验,让所有CSV数据都能先插入到脏表中,给触发器留足处理空间:

ALTER TABLE dirty_si_base MODIFY COLUMN fecha_fallo_notificacion VARCHAR(10);

步骤2:重新编写触发器(带错误捕获)

使用DECLARE CONTINUE HANDLER捕获STR_TO_DATE转换时的1292错误,标记无效日期并写入错误表。这里提供两种方案,可根据需求选择:

方案A:BEFORE INSERT触发器(提前处理脏数据)

在插入前校验,可将无效日期字段设为NULL,避免脏数据留存:

CREATE DEFINER=`root`@`localhost` TRIGGER `dirty_si_base_BEFORE_INSERT` BEFORE INSERT ON `dirty_si_base` FOR EACH ROW
BEGIN
    DECLARE fecha_valida BOOLEAN;
    DECLARE temp_date DATE;

    -- 捕获日期转换错误(错误码1292),标记日期无效
    DECLARE CONTINUE HANDLER FOR 1292
        SET fecha_valida = FALSE;

    -- 初始化标记为有效
    SET fecha_valida = TRUE;
    -- 尝试转换日期,若无效会触发上面的HANDLER
    SET temp_date = STR_TO_DATE(NEW.fecha_fallo_notificacion, '%Y-%m-%d');

    -- 日期无效时写入错误表,并将字段设为NULL(可根据需求调整)
    IF NOT fecha_valida THEN
        INSERT INTO errores_carga(con, mensaje, campo, archivo, created_at)
        VALUES (CAST(NEW.id AS CHAR), 'La fecha no existe', 5, 'SI', NOW());
        SET NEW.fecha_fallo_notificacion = NULL;
    END IF;
END;

方案B:AFTER INSERT触发器(保留原始数据)

插入后再校验,保留CSV中的原始无效日期字符串:

CREATE DEFINER=`root`@`localhost` TRIGGER `dirty_si_base_AFTER_INSERT` AFTER INSERT ON `dirty_si_base` FOR EACH ROW
BEGIN
    DECLARE fecha_valida BOOLEAN;
    DECLARE temp_date DATE;

    DECLARE CONTINUE HANDLER FOR 1292
        SET fecha_valida = FALSE;

    SET fecha_valida = TRUE;
    SET temp_date = STR_TO_DATE(NEW.fecha_fallo_notificacion, '%Y-%m-%d');

    IF NOT fecha_valida THEN
        INSERT INTO errores_carga(con, mensaje, campo, archivo, created_at)
        VALUES (CAST(NEW.id AS CHAR), 'La fecha no existe', 5, 'SI', NOW());
    END IF;
END;

步骤3:批量修正到目标表

当脏表数据处理完成后,可通过以下SQL将有效日期同步到目标表:

INSERT INTO 目标表(fecha_fallo_notificacion, 其他字段)
SELECT STR_TO_DATE(fecha_fallo_notificacion, '%Y-%m-%d'), 其他字段
FROM dirty_si_base
WHERE fecha_fallo_notificacion IS NOT NULL;

内容的提问来源于stack exchange,提问作者Julio Guerrero

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 11:27:36