PL SQL Oracle Триггер, суммирующий сумму в строках по id - PullRequest
0 голосов
/ 12 января 2020

У меня есть такие таблицы:

Таблица доставок:

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

и другая таблица производителей:

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

Идея состоит в том, чтобы создать триггер, который суммирует сумму отгрузки из таблицы Shippings для каждого производителя и обновляет ее в таблице Producers после любого изменения (UPDATE, DELETE, INSERT), если триггер работает, таблица 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;

/

если кто-нибудь может мне помочь, я буду благодарен! :)

Ответы [ 2 ]

1 голос
/ 12 января 2020

Зачем использовать для этого триггер? Являются ли данные настолько большими, что простая агрегация невозможна:

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;

Хотя ваш подход логически корректен, он делает больше работы чем необходимо, и, вероятно, приведет к ошибке триггера таблицы мутаций.

0 голосов
/ 13 января 2020

Для следующих таблиц:

Таблица отгрузок:

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

, а другая таблица - это Производители:

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

Вы можете объявить триггер на producers таблица, подобная этой:

create or replace trigger trg_producers 
BEFORE INSERT OR DELETE OR UPDATE
    ON producers
    FOR EACH ROW 
declare 
pragma autonomous_transaction;
producerShippedAmount number(10):=0;
begin

SELECT SUM(amount) INTO producerShippedAmount 
        FROM Shippings
        WHERE ProducernName = :NEW.Name;

:new.amount := producerShippedAmount;


end trg_producers;

Необходимо отметить, что pragma aut автономная_транзакция должна быть объявлена ​​

...