Как использовать данные из обновленной таблицы в триггере? - PullRequest
0 голосов
/ 12 января 2019

Итак, у меня есть две таблицы:

create table CURRENCY
(
     name VARCHAR2(40 CHAR) PRIMARY KEY,
     value NUMBER(6,2)
);

create table EXCHANGE_RATE
(
     currency1 references CURRENCY(name),
     currency2 references CURRENCY(name),
     price NUMBER(6,2),
     PRIMARY KEY(currency1, currency2)
);

Всякий раз, когда я вставляю новый CURRENCY, я хочу создать новый EXCHANGE_RATES между всеми предыдущими CURRIENCIES и новым. Допустим, у меня есть только одна валюта в моей таблице:

INSERT INTO CURRENCY VALUES("EURO", 2.0)

А теперь хочу вставить новый:

INSERT INTO CURRENCY VALUES("DOLLAR", 1.0)

Моя цель - вставить в EXCHANGE_RATE строки:

"EURO", "DOLLAR", 2.0
"DOLLAR", "EURO", 0.5

Какой лучший способ сделать это? Я пытался использовать AFTER INSERT OR UPDATE Триггер:

CREATE OR REPLACE TRIGGER new_currency
AFTER INSERT OR UPDATE
ON CURRENCY
FOR EACH ROW

BEGIN

INSERT INTO EXCHANGE_RATE (currency1, currency2, price)
SELECT name, :new.name, price/:new.price
FROM CURRENCY;

INSERT INTO EXCHANGE_RATE (currency1, currency2, price)
SELECT  :new.name, name, :new.price/price
FROM CURRENCY;

END;
/

но это не работает, так как мне нужно запросить таблицу CURRENCY, которая обновляется, и я просто получаю ORA-04091.

Как правильно это сделать?

1 Ответ

0 голосов
/ 12 января 2019

Вы не можете запросить таблицу, из-за которой сработал триггер внутри самого триггера.

Если бы я был вами, я рассмотрю возможность использования хранимых процедур. Просто переместите скрипт вставки в процедуру

CREATE PROCEDURE INS_CURRENCY (p_currency varchar2, p_price number) as
BEGIN
    INSERT INTO CURRENCY VALUES(p_currency , p_Price);

    INSERT INTO EXCHANGE_RATE (currency1, currency2, price)
    SELECT name, p_currency, price/p_price
    FROM CURRENCY
    WHERE NAME != p_current;

    INSERT INTO EXCHANGE_RATE (currency1, currency2, price)
    SELECT  p_currency, name, p_price/price
    FROM CURRENCY
    WHERE name != p_currency;
END;
...