DECLARE
L_valuediff REAL BEGIN
L_valuediff=NEW.extendedprice*(1-NEW.discount)*(1+NEW.tax); /*增加订单明细项后,计算订单含税折扣价总价的修正值*/ UPDATE Orders SET totalprice=totalprice+L_valuediff /*更新订单的含税折扣价总价*/ WHERE orderkey=NEW.orderkey; END;
(3)在Lineitem表上定义一个DELETE触发器,当删除一项订单明细时,自动修改订单Orders的TotalPrice,以保持数据一致性。
CREATE OR REPLACE TRIGGER TRI_Lineitem_Price_DELETE AFTER DELETE ON Lineitem FOR EACH ROW AS
DECLARE
L_valuediff REAL; BEGIN
L_valuediff=-OLD.extendedprice*(1-OLD.discount)*(1+OLD.tax); /*删除订单明细项后,计算订单含税折扣价总家的修正值*/ UPDATE Orders SET totalprice=totalprice+L_valuediff /*更新订单的含税折扣价总价*/ WHERE orderkey=NEW.orderkey; END;
(4)验证触发器TRI_Lineitem_Price_UPDATE。 /*查看1854号订单的含税折扣价总价totalprice*/ SELECT totalprice FROM Orders
WHERE orderkey=1854;
/*激活触发器,修改1854号订单第一个明细项的税率,该税率增加0.5%*/ UPDATE Lineitem SET tax=tax+0.005
WHERE orderkey=1854 AND linenumber=1;
/*再次查看1854号订单的含税折扣总价totalprice是否有变化,如有变化,则是触发器起作用了,否则触发器没有起作用*/ SELECT totalprice FROM Orders
WHERE orderkey=1854;
2.BEFORE触发器
(1)在Lineitem表上定义一个BEFORE_UPDATE触发器,当修改订单明细中的数量(quality)时,先检查供应表PartSupp中的可用数量availqty是否足够. CREAT ORREPLACE TRIGGER TRI_Lineitem_Quality_UPDATE BEFORE UPDATE OF quality ON Lineitem FOR EACH ROW AS
DECLARE
L_valuediff INSERT; L_availqty INSERT; BEGIN
/*计算订单明细项修改时,订购数量的变化值*/ L_valuediff=NEW.quantity-OLD.quantity;
/*查询当前订单明细项对应零件供应记录中的可用数量*/ SELECT availqty INTO L_availqty FROM PartSupp
WHERE partkey=NEW.partkey AND suppkey=NEW.suppkey;
IF(L_availqty-L_valuediff >=0) THEN BEGIN
/*如果可用数量可以满足订单订购数量,则提示ENOUGH*/ RAISE NOTICE ‘Available quantity is ENOUGH‘;
/*修改当前订单明细项对应零件供应记录中的可用数量*/ UPDATE PartSupp
SET availqty=availqty-L_valuediff
WHERE partkey=NEW.partkey AND suppkey=NEW.suppkey; END; ELSE
/*如果可用数量不能满足订单订购数量,则更新过程异常中断*/ RAISE EXCEPTION ‘Available quantity is NOT ENOUGH’; END IF; END;
(2)在Lineitem表上定义一个BEFORE INSERT触发器,当插入订单明细,先检查供应表PartSupp中的可用数量availqty是否足够。
CREATE OR REPLACE TRIGGER TRI_Lineitem_Quantity_UPDATE BEFORE INSERT ON Lineitem FOR EACH ROW AS
DECLARE
L_valuediff INSERT;
L_aavailqty INSERT; BEGIN
L_valuediff=NEW.quantity;/*获得插入订单明细项的订购数量*/ /*查询当前订单明细项对应零件供应记录中的可用数量*/ SELECT availqty INTO L_availqty FROM PartSupp
WHERE partkey=NEW.partkey AND suppkey=NEW.suppkey;
IF (L_availqty-L_valuediff >=0) THEN BEGIN
/*如果可用数量可以满足订单订购数量,则提示ENOUGH*/ RAISE NOTICE’Availqty quantity is ENOUGH’;
/*修改当前订单明细项对应零件供应记录中的可用数量*/ UPDATE PartSupp
SET availqty=availqty-L_valuediff
WHERE partkey=NEW.part AND suppkey=NEW.suppkey; END; ELSE
/*如果可用数量不能满足订单订购数量,则插入过程异常中断*/ RAISE EXCEPTION ‘Available quantity is NOT ENOUGH’; END IF; END;
(3)在Lineitem表上定义一个BEFORE DELETE触发器,当删除订单明细时,该订单明细项订购的数量要归还对应的零件供应记录。
CREATE OR REPLACE TRIGGER TRI_Lineitem_Quantity_UPDATE BEFORE DELETE ON Lineitem FOR EACH ROW AS
DECLARE
L_valuediff INSERT; L_availqty INSERT; BEGIN
/*获得删除订单明细项的订购数量*/ L_valuediff=-OLD.quantity;
/*修改当前订单明细项对应零件供应记录中的可用数量*/ UPDATE PartSupp
SET availqty=availqty-L_valuediff
WHERE partkey=NEW.partkey AND suppkey=NEW.suppkey; END;
(4)验证触发器TRI_Lineitem_Quantity_UPDATE。
/*查看1854号订单第1个明细项的零件和供应商编号、订购数量、可用数量*/ SELECT L.partkey,L.suppkey,L.quantity,PS.availqty FROM Lineitem L,PartSupp PS
WHERE L.partkey=PS.partkey AND L.suppkey=PS.suppkey AND L.orderkey=1854 AND L.linenumber=1;
/*激活触发器,修改1854号订单第1个明细项的订购数量*/ UPDATE Lineitem SET quantity=quantity+5; WHERE orderkey=1854 AND lineitem=1;
/*再次查看1854号订单第1个明细项的相关信息,以验证触发器是否起作用*、 SELECT L.partkey,L.suppkey,L.quantity,PS.availqty FROM Lineitem L,PartSupp PS
WHERE L.partkey=PS.partkey AND L.suppkey=PS.suppkey AND L.orderkey=1854 AND L.Linenumber=1;
3. 删除触发器
删除触发器TRI_Lineitem_Price_UPDATE。
DROP TRIGGER TRI_Lineitem_Price_UPDATE ON Lineitem;
四、实验心得
通过本次实验,进一步了解了触发器的定义,初步掌握了数据库触发器的设计和使用方法,成功动手设置了BEFORE触发器和AFTER触发器。实验过程中,由于基础知识薄弱与实践经验匮乏,遇到了不少难题,好在有老师和同学的帮助克服了困难。经过实践,更激励了我们继续努力学习,打好基础。