首页 > 解决方案 > PLSQL Oracle 触发器,按 id 对行中的金额求和

问题描述

我有这样的表:

出货表:

ProducernName| ... |Amount
A            |...  |1
B            |...  |2
A            |...  |5
C            |...  |3
C            |...  |5

和另一个生产者表:

Name|...| Shipped Amount
A   |...|  NULL
B   |...|  NULL
C   |...|  NULL

我们的想法是创建一个触发器,将 Shippings 表中每个生产者的发货量相加,并在任何更改(更新、删除、插入)后在 Producers 表上更新它,如果触发器工作,Producers 表将如下所示:

Name|...| Shipped Amount
A   |...|  6
B   |...|  2
C   |...|  8

我试图找到金额的总和并将其保存在我声明的变量中,但我不知道我的思维方向是否正确以及如何将总和插入到生产者表的正确行中。

CREATE TRIGGER SumShippedTrigger
AFTER INSERT OR DELETE OR UPDATE
OF amount
ON SHIPPINGS
FOR EACH ROW 
DECLARE
        producerShippedAmount NUMBER(10);
        producer VARCHAR2(10);
BEGIN
        SELECT SUM(amount) INTO producerShippedAmount 
        FROM Shippings
        WHERE producer= :NEW.producer;


    producer:= :NEW.procuder;
    END;

/

如果有人可以帮助我,我将不胜感激!:)

标签: sqloracleplsqldatabase-trigger

解决方案


为什么要为此使用触发器?数据是否如此庞大以至于无法进行简单的聚合:

select producer, sum(amount)
from shippings
group by producer;

您可以轻松地为单个生产者查找此内容(使用where),并使用索引使其更有效。

如果您确实使用触发器,我会说通常的方法是逐步更改总和:

CREATE TRIGGER SumShippedTrigger
    AFTER INSERT OR DELETE OR UPDATE OF amount
    ON SHIPPINGS
    FOR EACH ROW 
BEGIN
    UPDATE producers
        SET amount = COALESCE(amount, 0) + COALESCE(:new.amount, 0) - COALESCE(:old.amount, 0)
        WHERE producer = COALESCE(:NEW.producer, :OLD.producer);
END;

尽管您的方法在逻辑上是正确的,但它所做的工作比必要的要多,并且可能会导致变异表触发器错误。


推荐阅读