创建一个触发器,当更新一个表中的列时更新另一个表中的列

发布于 2024-08-29 18:30:32 字数 341 浏览 5 评论 0原文

我有两个表

Order(id, date, note)

Delivery(Id, Note, Date)

我想创建一个触发器,当订单中的日期更新时更新 Delivery 中的日期。

我正在考虑做类似

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

如何获取日期和行 ID?

谢谢

i have two tables

Order(id, date, note)

and

Delivery(Id, Note, Date)

I want to create a trigger that updates the date in Delivery when the date is updated in Order.

I was thinking to do something like

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

How do I get the date and row id?

thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

另类 2024-09-05 18:30:32

如何获取日期和行 ID?

假设这些是 ORDER 表中名为 DELIVERY_DATE 和 ID 的列,您的触发器应如下所示:

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 构造来测试是否执行交付更新。如果您的触发器中没有其他逻辑,您可以这样写...

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 似乎是它的逻辑位置。

How do i get the date and row id?

Assuming these are columns on your ORDER table called DELIVERY_DATE and ID your trigger should look something like this:

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;

Note the FOR EACH ROW clause: that is necessary to reference values from individual rows. I have used an IF construct to test whether to execute the UPDATE on Delivery. If you have no other logic in your trigger you could write it like this...

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;

I have answered the question you asked but, as an aside, I will point out that your data model is sub-optimal. A properly normalized design would hold DELIVERY_DATE on only one table: DELIVERY seems teh logical place for it.

你怎么这么可爱啊 2024-09-05 18:30:32

使用 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 包含为。示例:

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

如果您不想更改“old”和“new”的默认名称,则可以完全省略 REFERENCING 子句。

Use the OLD and NEW bind variables. OLD references the row or column being updated before the change is made; NEW references it after the change.

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;

You can modify the REFERENCING clause to give your bind variables different names. You can include OLD as <name> too. Example:

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

If you don't want to change the default names of "old" and "new", you can leave out the REFERENCING clause completely.

西瑶 2024-09-05 18:30:32

触发器中有一个隐式的新旧引用,其形式为:
REFERENCING OLD AS OLD NEW AS NEW

您可以写入 :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;

There is an implicit new and old reference in the trigger in the form of:
REFERENCING OLD AS OLD NEW AS NEW

You can write to the :NEW value but not to the :OLD value.

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;

Template:

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;
眼中杀气 2024-09-05 18:30:32

每当需要这种触发器时,请仔细查看您的设计。真的需要单独的交货记录吗?一个订单真的有超过1次送货吗?

触发器看起来不错,但它们确实很快就会把事情搞砸。

Whenever there is a need for this kind of trigger, have a good look at your design. Is there really a need for a separate delivery record? Does an order really have more than 1 delivery ?

Triggers seem nice but they do tend to mess things up pretty quickly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文