Sql 一个触发器,用于查找不同表中一个字段的和,如果超过oracle中的某个值,则会出错
我有两张桌子 moduleprogress包含以下字段: 学生 模块代码 模数式 包含以下字段的模块: 模块代码 学分 当用户试图在moduleprogress表中插入或更新数据时,我需要运行一个触发器 触发器需要: 查看用户输入的学生ID,并查看他们在moduleyear 1中学习的所有模块。 将模块编码为用户输入,并查看模块表,找到所有这些模块的学分字段总和。每个模块值10或20学分。 如果该值高于120年信用额度,则需要出错;如果没有,则输入正常。 这有意义吗?这可能吗 @没有名字的马 这看起来会起作用,但我只会使用数据库手动输入数据,所以它需要在输入时出错。我正试图得到一个类似的触发器来解决这个问题触发器不起作用,忘记了UOS_uuu比一切都重要。只是帮助我处理数据库和其他功能Sql 一个触发器,用于查找不同表中一个字段的和,如果超过oracle中的某个值,则会出错,sql,oracle,validation,triggers,sum,Sql,Oracle,Validation,Triggers,Sum,我有两张桌子 moduleprogress包含以下字段: 学生 模块代码 模数式 包含以下字段的模块: 模块代码 学分 当用户试图在moduleprogress表中插入或更新数据时,我需要运行一个触发器 触发器需要: 查看用户输入的学生ID,并查看他们在moduleyear 1中学习的所有模块。 将模块编码为用户输入,并查看模块表,找到所有这些模块的学分字段总和。每个模块值10或20学分。 如果该值高于120年信用额度,则需要出错;如果没有,则输入正常。 这有意义吗?这可能吗 @没有名字的马 这
CREATE OR REPLACE TRIGGER "UOS_TESTINGS"
BEFORE UPDATE OR INSERT ON UOS_MODULE_PROGRESS
REFERENCING NEW AS NEW OLD AS OLD
DECLARE
MODULECREDITS INTEGER;
BEGIN
SELECT
m.UOS_CREDITS,
mp.UOS_MODULE_YEAR,
SUM(m.UOS_CREDITS)
INTO MODULECREDITS
FROM UOS_MODULE_PROGRESS mp JOIN UOS_MODULES m
ON m.UOS_MODULE_CODE = mp.UOS_MODULE_CODE
WHERE mp.UOS_MODULE_YEAR = 1;
IF MODULECREDITS >= 120 THEN
RAISE_APPLICATION_ERROR(-20000, 'Students are only allowed to take upto 120 credits per year');
END IF;
END;
我收到错误消息:
8 23 PL/SQL:ORA-00947:值不足
4 1 PL/SQL:SQL语句被忽略我不确定我是否理解您的描述,但按照我的理解,这可以使用物化视图解决,它可能会提供比触发器更好的事务行为:
CREATE MATERIALIZED VIEW LOG
ON moduleprogress WITH ROWID (modulecode, studentid, moduleyear)
INCLUDING NEW VALUES;
CREATE MATERIALIZED VIEW LOG
ON modules with rowid (modulecode, credits)
INCLUDING NEW VALUES;
CREATE MATERIALIZED VIEW mv_module_credits
REFRESH FAST ON COMMIT WITH ROWID
AS
SELECT pr.studentid,
SUM(m.credits) AS total_credits
FROM moduleprogress pr
JOIN modules m ON pr.modulecode = m.modulecode
WHERE pr.moduleyear = 1
GROUP BY pr.studentid;
ALTER TABLE mv_module_credits
ADD CONSTRAINT check_total_credits CHECK (total_credits <= 120)
但是:根据表的大小,这可能比纯基于触发器的解决方案慢
此解决方案的唯一缺点是,错误将在提交时抛出,而不是在插入时抛出,因为MV仅在提交时刷新,然后计算检查约束您可能会在此处运行一个突变触发器问题。另外,插入多行的独立并发事务又如何呢。这种设计有一种难闻的味道。你需要更精确地知道触发器不工作到底意味着什么。顺便问一下:UOS\U模块的数据类型是什么?如果是数值列,则不应对值1使用单引号。@JMoorhouse:如果仅插入单行,则可以在自动提交模式下执行此操作,然后立即得到错误。仅插入单行。如何使用自动提交模式?@JMoorhouse:这取决于您的编程环境。在Java/JDBC中,只需在底层连接上调用setAutoCommittrue。