《数据库系统原理》实验报告

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触发器。实验过程中,由于基础知识薄弱与实践经验匮乏,遇到了不少难题,好在有老师和同学的帮助克服了困难。经过实践,更激励了我们继续努力学习,打好基础。

联系客服:779662525#qq.com(#替换为@) 苏ICP备20003344号-4