解决 err in before insert trigger on pl/sql

问题描述 投票:0回答:1

我创建表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 触发器执行时执行

plsql triggers oracle-apex apex apex-code
1个回答
0
投票

带日期的演习太多;为什么?日期应该作为日期处理,不要把事情复杂化。 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 文字,由
    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
数据类型列是一个好主意。过去不是,现在不是,以后也不会。

© www.soinside.com 2019 - 2024. All rights reserved.