PL/SQL插入前触发器执行异常求助:ORA-01841错误排查
问题解决方法
首先,错误ORA-01841的根源是触发器里做了多余且错误的日期转换:把DATE类型的sysdate和:new.BIRTH_day先转成字符串,再转回DATE,而且转回时未指定匹配的格式掩码,导致数据库用默认日期格式解析时出错。
比如当birth_day为08/09/2000时,to_char(:new.BIRTH_day,'DD-MM-YYYY')生成的字符串是08-09-2000,调用TO_DATE时没指定格式,数据库会用当前会话的NLS_DATE_FORMAT(比如默认的DD/MM/YYYY)去解析,字符串里的-分隔符和默认格式的/不匹配,导致年份解析失败,触发ORA-01841错误。
修正后的触发器代码
直接去掉多余的日期转换,MONTHS_BETWEEN函数本身支持直接传入DATE类型参数:
create or replace trigger p before insert on b for each row declare g number; begin -- 直接使用DATE类型计算,无需转字符串再转DATE g := MONTHS_BETWEEN(sysdate, :new.BIRTH_day)/12; IF (g < 18) THEN RAISE_APPLICATION_ERROR(-20000,'VV'); END IF; IF (g > 18) THEN RAISE_APPLICATION_ERROR(-20000,'ll'); END IF; end; /
额外说明
原触发器逻辑未处理g = 18的情况,此时插入数据不会触发任何报错。如果需要限制仅刚好18岁的记录能插入,可补充对应逻辑,比如:
IF (g = 18) THEN -- 允许插入或添加自定义提示 NULL; END IF;
内容的提问来源于stack exchange,提问作者mostafa majidi
相关产品推荐
相关产品推荐

