错误:-> PLS-00382:表达式类型错误

时间:2020-01-11 12:02:49

标签: oracle plsql database-trigger

什么是失败触发????我正在尝试创建一个触发器,当找到日期时间时将其激活 在时间间隔上。

 CREATE TABLE R
 (
  OID_R     NUMBER NOT NULL,
  Price     INTEGER NOT NULL,
  f         DATE    NOT NULL,
  HourStart DATE    NOT NULL,
  HuorFin   DATE    NOT NULL,
  OID_E     NUMBER          ,
  OID_S     NUMBER          ,
  OID_P     NUMBER NOT NULL
 );

CREATE OR REPLACE TRIGGER TR_D
  BEFORE INSERT OR UPDATE OF OID_R ON R
  FOR EACH ROW
DECLARE
  IntervalR DATE;
  HourStart DATE;
  HourFin   DATE;
BEGIN
  IntervalR := :new.HourFin - :new.HourStart;
  IF IntervalR BETWEEN :old.HourStart AND :old.HourFin THEN
    raise_application_error(-20000, 'Is not avaible');
  END IF;
END;

1 个答案:

答案 0 :(得分:0)

您的描述为“在时间间隔上找到日期时间时”,然后测试新值之间的差是否落在旧值之间。这永远不会起作用,但是您要解决的实际问题似乎是“确定新时间是否与旧时间重叠或可以重新设置时间”。
除了误解从另一个日期减去一个日期的结果之外,触发器还有一些根本的缺陷。您的触发器在插入时触发,但随后使用旧行中的列,但是在插入时没有旧行,因此对其进行的所有操作都将为NULL。因此,您的IF语句永远不会正确。因此,无需在刀片上开火。触发器也会在更新时触发,但不会触发任何更新。仅当更新OID_R列时,如果OID_R不是集合列表中的列,则触发器不会在更新时触发。似乎OID_R是(或至少应该是)主键,在正常操作期间,OID_R不应从不进行更新。因此,切勿在更新时触发。您定义了三个变量,一个不正确,另外两个未使用,因此不需要。我们剩下的原始问题是:新时代与旧时代是否重叠
让我们在以下情况下定义有效的重置:

  1. 新终点大于新起点
  2. 当前时间小于新的开始时间
  3. 当前时间小于以前的时间

我们得到(注意可能还有其他条件)

create or replace trigger tr_d
  before  update on r
  for each row
begin
   if not (    new.endhour > :new.starthour  
           and sysdate     < :new.starthour
           and sysdate     < :old.starthour
          )
   then 
        raise_application_error(-20000, 'is not avaible');
  end if;
end tr_d;

一个悬而未决的问题是“时间代表每天重复的值(即仅重复一次)还是表示特定日期的时间?如果每天重复一次,则需要从值和日期中去除日,月,年。