【发布时间】:2017-08-04 23:27:01
【问题描述】:
我需要一些帮助,因为我看不出这段代码的问题在哪里。
我有 2 张桌子。产品(id,..,currentPrice) 和价格(id, product_id, date, price)。我需要创建触发器和程序,当 Prices.price 中的值被插入、更新或删除时,它们将自动更新 Products.currentPrice 中的值。 我创建了一个包、两个触发器和一个过程,它们都可以编译,但是当我插入、更新或删除一个值时,什么也没有发生。 但是,当我手动调用过程并插入 product_id (例如 Products 表中现有产品的值 1 )时,Products.currentPrice 中 id 为 1 的产品的值每次都会更新。 我猜 BEFORE 触发器的值没有保存在 PACKAGE 变量中,因为我收到“找不到数据”错误。 我正在使用 SQL Developer 和 Oracle 11g XE。
这是我的代码:
CREATE OR REPLACE PACKAGE mypackage IS
gid NUMBER;
END;
CREATE OR REPLACE TRIGGER trg_currentprice1
BEFORE INSERT OR UPDATE OR DELETE ON prices
FOR EACH ROW
BEGIN
IF (INSERTING OR UPDATING) THEN
BEGIN
mypackage.gid := :new.product_id;
END;
ELSE
BEGIN
mypackage.gid := :old.product_id;
END;
END IF;
END;
CREATE OR REPLACE TRIGGER trg_currentprice2
AFTER INSERT OR UPDATE OR DELETE ON prices
DECLARE
v_id NUMBER := mypackage.gid;
BEGIN
calc_currentprice(v_id);
END;
CREATE OR REPLACE PROCEDURE calc_currentprice(prodid IN NUMBER) AS
curprice Products.currentPrice%TYPE;
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
curprice := 0;
SELECT price INTO curprice FROM prices
WHERE product_id = prodid AND date = (SELECT MAX(date) FROM prices WHERE product_id = prodid AND date <= SYSDATE);
EXECUTE IMMEDIATE 'ALTER TRIGGER trg_products_forbid2 DISABLE';
UPDATE products
SET currentPrice = curprice
WHERE product_id = prodid;
EXECUTE IMMEDIATE 'ALTER TRIGGER trg_products_forbid2 ENABLE';
END;
【问题讨论】:
-
同意 unleashed - 您不应该使用自主事务,也不应该在此处更改触发器。为什么不包括以下事实的众多原因之一:更改触发器是一项全局操作并影响所有会话,而不仅仅是当前会话。
标签: database oracle plsql triggers procedure