我正在验证通过
LOAD DATA LOCAL INFILE
导入到数据库的 csv 文件,并使用 before insert trigger
来实现这一点(这是一个脏表,因此当此过程完成时,我会将正确的数据批量传输到另一个表)。问题是我有一个日期字段(Y-m-d),如果脚本读取不存在的日期(例如:2023-09-31、2023-02-30),它会抛出:
无效的日期时间格式:1292 截断的不正确日期值:'2023-09-31'。
我试图*捕获*触发器中的错误,但它总是在我的前端显示相同的错误。
这是我的触发器的一部分。
CREATE DEFINER=`root`@`localhost` TRIGGER `dirty_si_base_AFTER_INSERT` AFTER INSERT ON `dirty_si_base_AFTER_INSERT` FOR EACH ROW BEGIN
[...]
DECLARE fecha_valida_notificacion BOOLEAN;
[...]
-- Verificamos si la fecha fallo es válida
SET fecha_valida_notificacion = (
STR_TO_DATE(NEW.fecha_fallo_notificacion, '%Y-%m-%d') IS NOT NULL AND
STR_TO_DATE(NEW.fecha_fallo_notificacion, '%Y-%m-%d') = NEW.fecha_fallo_notificacion
);
-- Si la fecha no es válida, ingresamos a la tabla de errores
IF NOT fecha_valida_notificacion 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
我希望处理此错误并像其他错误一样在另一个表中插入一条消息。
尝试:
使用临时变量来解析日期: 您可以使用临时变量来保存解析后的日期,然后进行比较,而不是直接将解析后的日期与原始日期字符串进行比较。
同时使用
NULLIF
和 STR_TO_DATE
:
如果日期字符串与预期格式不匹配,NULLIF
可用于返回NULL
。
我的更新版本:
CREATE DEFINER=`root`@`localhost` TRIGGER `dirty_si_base_AFTER_INSERT`
AFTER INSERT ON `dirty_si_base_AFTER_INSERT` FOR EACH ROW
BEGIN
DECLARE tempDate DATE;
DECLARE fecha_valida_notificacion BOOLEAN;
-- Attempt to parse the date
SET tempDate = NULLIF(STR_TO_DATE(NEW.fecha_fallo_notificacion, '%Y-%m-%d'), NEW.fecha_fallo_notificacion);
-- Check if the parsed date is NULL (indicating a parse failure)
SET fecha_valida_notificacion = (tempDate IS NOT NULL);
-- If the date is not valid, insert a record into the errores_carga table
IF NOT fecha_valida_notificacion 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;
您还应该注意,对于日期和日期部分 日期时间值,
(仅)检查单个年份, 有效的月份和日期值。更准确地说,这 意味着检查年份以确保它在范围内 0-9999(含),检查月份以确保其在范围内 范围 1-12(含),并检查月份中的某一天以确保 它在 1-31 范围内(含),但服务器不检查 值的组合。例如,STR_TO_DATE()
返回SELECT STR_TO_DATE('23-2-31', '%Y-%m-%d')
。2023-02-31
STR_TO_DATE
简而言之:
STR_TO_DATE
认为 2023-02-31
以及 2023-09-31
都是有效的。
DATE()
相反,它将针对 NULL
和 2023-02-31
返回 2023-09-31
。