oracle - 当状态处于活动状态时,如何制作一个 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>
有什么建议么?
解决方案
您的触发器在编写时工作得很好。但是,显然不是你想要的或期望的。您想要的是将传入行的费用降低 1/2。但是,您的期望是错误的。您的更新语句实际上所做的是将表中现有行的费用降低 1/2 。由于传入的行还不存在,它不参与更新。这就是为什么它似乎适用于某些但不是所有的插入。(实际上我很惊讶,因为我预计会出现“ORA-04091:表正在变异......”异常)。原因是您的 Update 语句没有 WHERE 子句,因此它更新每一行。看这里一个小提琴,通过在每次插入后显示表格来显示正在发生的事情,以查看该语句实际做了什么。当结果不如预期时,这通常是一种有用的技术。@SayanMalakshinov 是正确的:不要更新而是做一个作业。
:new.fees := :new.fees * .5;
推荐阅读
- c# - 转换时输入字符串的格式不正确,将值插入循环内的数据库
- sql - SQL Server Management Studio 需要完整的表路径
- django - DjangoForm 类元覆盖
- excel - 如何明智地使用高级过滤行
- excel - 想要一个包含非连续单元格的命名列表
- javascript - '[nodemon] 应用程序崩溃 - 在开始之前等待文件更改......'
- java - RESTful 重定向到基于单选按钮选择的路径
- android - 第二个动画从屏幕顶部开始,而不是前一个动画的位置
- android - 在 adb shell 中选择选项卡式数据而不使用 awk,因为使用 awk 会出现“awk not found error”
- html - 如何将文本从输入保存到角度变量?