delimiter $$ create trigger t_cjinsert before insert on xs_kc for each row begin declare xf int; set xf=(select 学分 from kc where 课程号=new.课程号); set new.学分=xf; if new.成绩>=60 then if (select 总学分 from xsqk where 学号=new.学号) is not null then update xsqk set 总学分=总学分+xf where 学号=new.学号; else update xs_kc set 学分=xf where 学号=new.学号 ; end if; end if; end; $$ delimiter; insert xs_kc(学号,课程号,成绩)values('2021130105','102',65);为什么最后一条插入语句失败
时间: 2024-01-05 08:04:25 浏览: 27
根据你提供的触发器代码,当插入一条新的记录到 `xs_kc` 表时,会自动为该记录计算学分,并更新学生的总学分。但是,在最后一条插入语句中,插入的成绩是 65 分,因此触发器不会更新学生的总学分,而是直接更新了 `xs_kc` 表中的学分字段,但是在你的数据库中,`xs_kc` 表中没有学号为 '2021130105' 的记录,因此插入语句失败。
如果你想要插入一条新的记录并触发触发器,可以将成绩设置为 60 分或以上,或者手动先插入一条记录到 `xs_kc` 表中,再执行插入语句。
相关问题
解释一下这段代码:delimiter $$ create trigger insert_stu after insert on Student for each row begin declare @cid varchar(30); select @cid=Cid from inserted; update Class set Cnumber = Cnumber + 1 where Cid = @cid; end; $$ delimiter ;
这段代码是用于创建一个触发器 (trigger)。触发器是一种特殊的数据库对象,可以在数据库表中的数据发生变化时自动执行特定的操作。
具体来说,这个触发器的名称是 `insert_stu`,它会在 `Student` 表中插入一条记录之后自动触发。`for each row` 表示每插入一行记录就会触发一次该触发器。
在触发器的主体部分,首先声明了一个名为 `@cid` 的变量。这个变量是用来存储插入到 `Student` 表中的记录的 `Cid` 字段值。`declare` 表示声明变量,`varchar(30)` 表示该变量是一个长度为 30 的字符串类型。
接下来,使用 `select` 语句从 `inserted` 表中获取新插入的记录的 `Cid` 字段值,并将其赋值给 `@cid` 变量。`inserted` 是一个特殊的表,用于存储触发器所依赖的数据。在这个例子中,`inserted` 表中存储了新插入的 `Student` 记录的所有字段值。
最后,使用 `update` 语句更新 `Class` 表中的记录,将 `Cnumber` 字段的值增加 1。`where` 子句用于指定更新哪些记录,这里是根据 `Cid` 字段的值来匹配。这表示当向 `Student` 表中插入一条记录时,与该记录相关联的 `Class` 表中的 `Cnumber` 字段值都会自动加 1。
DELIMITER $$ CREATE TRIGGER ypxz AFTER INSERT ON CF FOR EACH ROW BEGIN DECLARE n INT; SELECT Sl INTO n FROM inserted; IF n >= 20 THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '处方药品超过最大限度'; ROLLBACK; END IF; END$$ DELIMITER ; 1422 - Explicit or implicit commit is not allowed in stored function or trigger.
这个错误是因为你在触发器中使用了ROLLBACK语句,而这个语句会隐式地提交事务。在MySQL中,触发器是不能包含事务控制语句的,包括COMMIT、ROLLBACK以及START TRANSACTION等。
解决这个问题的方法是将触发器中的ROLLBACK语句替换为SIGNAL语句,用来抛出一个异常,告诉MySQL要回滚事务。你可以在SIGNAL语句中设置一个错误消息,用来告诉用户出现了什么问题。下面是一个修改后的触发器代码示例:
DELIMITER $$
CREATE TRIGGER ypxz
AFTER INSERT ON CF
FOR EACH ROW
BEGIN
DECLARE n INT;
SELECT Sl INTO n FROM inserted;
IF n >= 20 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '处方药品超过最大限度';
END IF;
END$$
DELIMITER ;
请注意,我将ROLLBACK替换为了SIGNAL语句,并设置了SQLSTATE和MESSAGE_TEXT属性。这样,当触发器条件不满足时,MySQL会抛出一个异常,并回滚事务。