Подтвердить что ты не робот

Создайте триггер, который обновляет столбец в одной таблице, когда обновляется столбец в другой таблице

У меня есть две таблицы

Заказ (id, дата, примечание)

и

Доставка (Id, Note, Date)

Я хочу создать триггер, который обновляет дату в Delivery, когда дата обновляется в Order.

Я думал сделать что-то вроде

CREATE OR REPLACE TRIGGER your_trigger_name
BEFORE UPDATE
ON Order
DECLARE
BEGIN
   UPDATE Delivery set date = ??? where id = ???
END;

Как получить идентификатор даты и строки?

спасибо

4b9b3361

Ответ 1

Как получить идентификатор даты и строки?

Предположим, что это столбцы на вашей таблице ORDER, называемые DELIVERY_DATE, и идентификатор вашего триггера должен выглядеть примерно так:

CREATE OR REPLACE TRIGGER your_trigger_name
    BEFORE UPDATE ON Order
    FOR EACH ROW 
BEGIN
   if :new.delivery_date != :old.delivery_date
   then
       UPDATE Delivery d
       set d.delivery_date = :new.delivery_date
       where d.order_id = :new.id;
    end if;
END;

Обратите внимание на предложение FOR EACH ROW: это необходимо для ссылки на значения из отдельных строк. Я использовал конструкцию IF для проверки выполнения UPDATE при поставке. Если у вас нет другой логики в вашем триггере, вы можете написать ее так:

CREATE OR REPLACE TRIGGER your_trigger_name
    BEFORE UPDATE OF delivery_date ON Order
    FOR EACH ROW 
BEGIN
   UPDATE Delivery d
   set d.delivery_date = :new.delivery_date
   where d.order_id = :new.id;
END;

Я ответил на заданный вами вопрос, но, как и в сторону, я укажу, что ваша модель данных неоптимальна. Правильно нормализованный дизайн будет содержать DELIVERY_DATE только в одной таблице: DELIVERY кажется логичным местом для него.

Ответ 2

В триггере есть неявная новая и старая ссылка в виде: ССЫЛКА НА СТАРОСТИ С НОВЫМ НОВЫМ

Вы можете записать в значение: NEW, но не в значение: OLD.

UPDATE Delivery set date = :new.delivery_date where id = :new.id;


CREATE OR REPLACE TRIGGER "BUR_TABLENAME" BEFORE
UPDATE ON "TABLE" FOR EACH ROW
BEGIN
  If :new.active_date is not null Then
    :new.active_date := TRUNC(:new.active_date);
End If;
END;

Шаблон:

CREATE OR REPLACE TRIGGER TRIGGER_NAME
 BEFORE
 UPDATE
 ON TABLE_NAME
 REFERENCING OLD AS OLD NEW AS NEW
 FOR EACH ROW
DECLARE
   V_VARIABLE   NUMBER (1);
BEGIN
   //Do Stuff;
  null;
end;

Ответ 3

Используйте переменные связывания OLD и NEW. OLD ссылается на обновляемую строку или столбец до внесения изменений; NEW ссылается на него после изменения.

CREATE OR REPLACE TRIGGER trig1
    BEFORE UPDATE
    ON order  REFERENCING NEW AS new
    FOR EACH ROW
BEGIN
    UPDATE delivery
       SET ddate   = :new.ddate
     WHERE id = :new.id;
END;

Вы можете изменить предложение REFERENCING, чтобы дать вашим переменным связывания разные имена. Вы можете включить OLD as <name> тоже. Пример:

CREATE OR REPLACE TRIGGER trig1
    BEFORE UPDATE
    ON order REFERENCING OLD AS old_values NEW AS new_values
    ...

Если вы не хотите изменять имена по умолчанию "старый" и "новый", вы можете полностью исключить предложение REFERENCING.

Ответ 4

Всякий раз, когда есть необходимость в этом типе триггера, посмотрите на свой дизайн. Есть ли необходимость в отдельной записи о доставке? У заказа действительно есть более одной доставки?

Триггеры кажутся приятными, но они, как правило, довольно быстро меняют вещи.