ОШИБКА: -> PLS-00382: выражение имеет неправильный тип - PullRequest
0 голосов
/ 11 января 2020

что за сбой на триггере ???? Я пытаюсь создать триггер, который будет активирован при обнаружении даты и времени на интервале времени.

 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 голосов
/ 13 января 2020

Ваше описание говорит, что "когда дата / время найдены на интервале времени", вы проверяете, находится ли разница между новыми значениями между старыми значениями. Это никогда не сработает, но похоже, что реальная проблема, которую вы пытаетесь решить, это «определить, перекрывают ли новые времена старые или их можно сбросить». У вашего триггера есть фундаментальный fl aws, за исключением неправильного понимания результата вычитания одной даты из другой. Ваш триггер срабатывает при вставке, но затем использует столбец из старой строки, но при вставке нет старой строки, поэтому все операции с ним приводят к NULL. Поэтому ваше утверждение IF никогда не может быть правдой. Так что нет необходимости стрелять по вставке. Триггер также срабатывает при обновлении, но не при любом обновлении. Только при обновлении столбца 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;

Остается вопрос: «Представлять ли времена значения, повторяющиеся ежедневно (только ie раз), или указать раз на указанную c дату? Если повторяется ежедневно, вам нужно убрать день, месяц, год из значений и sysdate.

...