首页 > 解决方案 > 当状态处于活动状态时,如何制作一个 PL/SQL 程序来更新学生费用?

问题描述

我是 PL/SQL 的新手,我有一个名为STUDENT的表,它包含以下列:REGNO, NAME, FNAME, DOMICILE, FEES, STATUS。我想要做的是创建新记录时,如果学生住所,例如DOMICILE = 'TEXAS'STATUS = 'ACTIVE'然后我想在FEES中提供 50% 的折扣。这是我的代码:

CREATE OR REPLACE TRIGGER MYTRIGGER
BEFORE INSERT ON STUDENT
FOR EACH ROW
BEGIN
IF :NEW.DOMICILE = 'TEXAS' AND :NEW.STATUS = 'ACTIVE' THEN
UPDATE STUDENT SET FEES = FEES - 0.50 * FEES;
END IF;
END MYTRIGGER;
/

触发器已创建,但无法正常工作.. 示例:

SQL> INSERT INTO STUDENT VALUES(1,'MARK','SMITH','TEXAS',5000,'ACTIVE');

1 row created.

SQL> SELECT * FROM STUDENT;

     REGNO NAME                           FNAME                          DOMICILE                          FEES STATUS
---------- ------------------------------ ------------------------------ ------------------------------ ---------- --------------------
         1 MARK                           SMITH                          TEXAS                                5000 ACTIVE

SQL> INSERT INTO STUDENT VALUES(2,'JAMES','FORD','TEXAS',5000,'ACTIVE');

1 row created.

SQL> INSERT INTO STUDENT VALUES(3,'SAM','MILLER','NEW JERSEY',5000,'ACTIVE');

1 row created.

SQL> SELECT * FROM STUDENT;

     REGNO NAME                           FNAME                          DOMICILE                          FEES STATUS
---------- ------------------------------ ------------------------------ ------------------------------ ---------- --------------------
         1 MARK                           SMITH                          TEXAS                                2500 ACTIVE
         2 JAMES                          FORD                           TEXAS                                5000 ACTIVE
         3 SAM                            MILLER                         NEW JERSEY                           5000 ACTIVE

SQL>

有什么建议么?

标签: oracleplsql

解决方案


您的触发器在编写时工作得很好。但是,显然不是你想要的或期望的。您想要的是将传入行的费用降低 1/2。但是,您的期望是错误的。您的更新语句实际上所做的是将表中现有行的费用降低 1/2 。由于传入的行还不存在,它不参与更新。这就是为什么它似乎适用于某些但不是所有的插入。(实际上我很惊讶,因为我预计会出现“ORA-04091:表正在变异......”异常)。原因是您的 Update 语句没有 WHERE 子句,因此它更新每一行。看这里一个小提琴,通过在每次插入后显示表格来显示正在发生的事情,以查看该语句实际做了什么。当结果不如预期时,这通常是一种有用的技术。@SayanMalakshinov 是正确的:不要更新而是做一个作业。

:new.fees := :new.fees * .5;

推荐阅读