Возникли проблемы при создании триггера, который обновляет столбец на основе переменной - PullRequest
0 голосов
/ 25 апреля 2018

Я пытаюсь создать триггер для класса, который обновляет баланс клиента в зависимости от того, на сколько дней позже или раньше был возвращен товар.У меня есть чартерная таблица с датой и датой возврата, триггер предназначен для срабатывания только при обновлении даты возврата.Затем триггер берет разницу между датой возврата и датой исполнения и сохраняет это значение в переменной.У меня есть ряд утверждений if else, которые определяют, был ли товар возвращен с опозданием или досрочно, а затем умножают количество дней на плату за просрочку или ранний бонус.Затем он обновляет баланс клиента в таблице клиентов до значения переменной комиссии.Oracle говорит, что у меня есть синтаксическая ошибка в моей конечной инструкции, и я не уверен, что не так.

CREATE OR REPLACE TRIGGER Fee_Trigger
AFTER UPDATE ON CHARTER
FOR EACH ROW 
WHEN ((:NEW.Return_Date <> :OLD.Return_Date AND :NEW.Return_Date IS NOT 
NULL))
DECLARE
Fee NUMBER; 
BEGIN 
Fee := (:NEW.Return_Date - Due_Date); 
IF Fee > 0 THEN Fee := (Fee * 75) ;
ELSE IF Fee < 0 THEN Fee := (Fee * 25);
ELSE IF Fee = 0 THEN FEE := Fee;
END IF;
UPDATE CUSTOMER 
SET Customer_Balance = Fee
WHERE CustomerID = :NEW.CustomerID
END;

Ответы [ 2 ]

0 голосов
/ 25 апреля 2018

Я предлагаю заменить операторы IF/ELSIF на выражение CASE в выражении UPDATE:

CREATE OR REPLACE TRIGGER Fee_Trigger
  AFTER UPDATE ON CHARTER
  FOR EACH ROW 
  WHEN ((:NEW.Return_Date <> :OLD.Return_Date AND :NEW.Return_Date IS NOT NULL))
DECLARE
  Due_Date                      DATE := TRUNC(SYSDATE); -- initialization as an example value.
  nDays_between_return_and_due  NUMBER;
BEGIN
  nDays_between_return_and_due := TRUNC(:NEW.Return_Date - Due_Date);

  UPDATE CUSTOMER 
    SET Customer_Balance = CASE
                             WHEN nDays_between_return_and_due > 0 THEN  -- Returned late
                               nDays_between_return_and_due * 75
                             WHEN nDays_between_return_and_due < 0 THEN  -- Returned early
                               nDays_between_return_and_due * 25
                             ELSE  -- Returned on time
                               0
                           END
    WHERE CustomerID = :NEW.CustomerID;
END FEE_TRIGGER;

Удачи.

0 голосов
/ 25 апреля 2018

Есть небольшие ошибки форматирования.В качестве альтернативы может использоваться следующее:

CREATE OR REPLACE TRIGGER Fee_Trigger
AFTER UPDATE ON CHARTER
FOR EACH ROW 
WHEN ((NEW.Return_Date <> OLD.Return_Date AND NEW.Return_Date IS NOT NULL))
DECLARE
 Fee NUMBER; 
BEGIN 
 Fee := :NEW.Return_Date - :NEW.Due_Date; 

 IF    Fee > 0 THEN Fee := (Fee * 75); 
 ELSIF Fee < 0 THEN Fee := (Fee * 25);
 ELSIF Fee = 0 THEN Fee := Fee;
 END IF;

 UPDATE CUSTOMER 
    SET Customer_Balance = Fee
  WHERE CustomerID = :NEW.CustomerID;

END;

Обнаружены следующие проблемы:

  • Не определена дата_для (может использоваться :OLD.Due_Date или :NEW.Due_Date)
  • ELSIF следует использовать вместо ELSE IF
  • UPDATE оператор должен заканчиваться semicolon.
  • Удалить colons до OLD и NEW внутри WHEN оператора.
...