我创建表b
create table b(
id number(3),
name varchar2(5),
birth_day date
);
&我创建触发器p
create or replace trigger p
before insert on b
for each row
declare
g number;
begin
SELECT MONTHS_BETWEEN(TO_DATE(to_char (sysdate,'DD-MM-YYYY')), TO_DATE (to_char(:new.BIRTH_day,'DD-MM-YYYY')))/12
INTO g FROM DUAL;
IF (g< 18) THEN
RAISE_APPLICATION_ERROR(-20000,'VV');
END IF;
IF (g> 18) THEN
RAISE_APPLICATION_ERROR(-20000,'ll');
end if;
end;
在b表birth_day行'08/09/2001'输入数据时 执行p触发器但是在b表birth_day行'08/09/2000'输入数据时 它不运行 p 触发器 & 显示此错误:'error ORA-01841: (full) year must be between -4713 and +9999, and not be 0' 这样我就可以在键入“08/09/2000”时执行 p 触发器 我该怎么办?
我想在 08/09/2000 p 触发器执行时执行
带日期的演习太多;为什么?日期应该作为日期处理,不要把事情复杂化。 08/09/2001 是一个字符串;使用日期文字(如我的示例所示)或具有适当格式模型的
to_date
函数。
SQL> create or replace trigger p
2 before insert on b
3 for each row
4 declare
5 g number;
6 begin
7 g := months_between(trunc(sysdate), :new.birth_day) / 12;
8
9 IF (g< 18) THEN
10 RAISE_APPLICATION_ERROR(-20000,'VV');
11 END IF;
12
13 IF (g> 18) THEN
14 RAISE_APPLICATION_ERROR(-20000,'ll');
15 end if;
16 end;
17 /
Trigger created.
测试:
SQL> insert into b (id, name, birth_day) values
2 (1, 'Mike', date '1970-02-03');
insert into b (id, name, birth_day) values
*
ERROR at line 1:
ORA-20000: ll
ORA-06512: at "SCOTT.P", line 11
ORA-04088: error during execution of trigger 'SCOTT.P'
SQL> insert into b (id, name, birth_day) values
2 (1, 'Mike', date '2022-02-03');
insert into b (id, name, birth_day) values
*
ERROR at line 1:
ORA-20000: VV
ORA-06512: at "SCOTT.P", line 7
ORA-04088: error during execution of trigger 'SCOTT.P'
SQL> insert into b (id, name, birth_day) values
2 (1, 'Mike', date '2005-03-11');
1 row created.
SQL>
测试你的日期值;当你说 08/09/2001 时,不清楚是 9 月 8 日 (dd/mm/yyyy) 还是 8 月 9 日 (mm/dd/yyyy),所以 - 给你,这两个选项。两种情况下的结果都是
VV
。
SQL> insert into b (id, name, birth_day) values
2 (1, 'Mike', date '2020-09-08');
insert into b (id, name, birth_day) values
*
ERROR at line 1:
ORA-20000: VV
ORA-06512: at "SCOTT.P", line 7
ORA-04088: error during execution of trigger 'SCOTT.P'
SQL> insert into b (id, name, birth_day) values
2 (1, 'Mike', date '2020-08-09');
insert into b (id, name, birth_day) values
*
ERROR at line 1:
ORA-20000: VV
ORA-06512: at "SCOTT.P", line 7
ORA-04088: error during execution of trigger 'SCOTT.P'
2000 年也没有问题(但现在由于年数不同,结果不同):
SQL> insert into b (id, name, birth_day) values
2 (1, 'Mike', date '2000-08-09');
insert into b (id, name, birth_day) values
*
ERROR at line 1:
ORA-20000: ll
ORA-06512: at "SCOTT.P", line 11
ORA-04088: error during execution of trigger 'SCOTT.P'
SQL>
再次:您尝试插入的值,从字面上看,
'08/09/2000'
是一个string;它包含在单引号中。您依靠 Oracle 的功能将该字符串隐式转换为有效的 DATE
数据类型值。为什么DATE
?因为您以这种方式创建了表:
create table b(
id number(3),
name varchar2(5),
birth_day date --> this; column's datatype is DATE
);
因此,您应该在该列中插入适当的数据类型值 -
DATE
.
你可以使用
date
关键字和用单引号括起来的值组成,格式为 yyyy-mm-dd
date '2023-03-11'
是今天的日期,2023 年 3 月 11 日to_date
函数,其格式模型遵循您传递的值
to_date('11.03.2023', 'dd.mm.yyyy')
你应该 not 尝试插入任何格式的字符串。 Oracle 可能无法识别它。如果没有,它将返回错误。如果成功,您计算机上的代码可能会工作,但是将该应用程序移植到另一个 NLS 设置与您之前服务器上的设置不同的数据库将以错误告终。现在想象一堆依赖于隐式转换的代码......你会非常抱歉你认为将字符串传递给
DATE
数据类型列是一个好主意。过去不是,现在不是,以后也不会。