我创建了包含触发器的名为student的表。我想通过SP将数据插入此表。当我执行SP(或将记录插入表的常规方式)时,它会给出以下错误。
“无法更新存储函数/触发器中的表'student',因为调用此存储函数/触发器的语句已使用该表。”
这是我的桌子:

CREATE TABLE IF NOT EXISTS `crd`.`student` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(255) NOT NULL,
  `age` INT(11) NOT NULL,
  `stuCode` VARCHAR(10) NOT NULL,
  PRIMARY KEY (`id`))
ENGINE = InnoDB
AUTO_INCREMENT = 45
DEFAULT CHARACTER SET = utf8mb4

我的触发器是:
delimiter $$
create trigger genCode BEFORE INSERT on student for each row
BEGIN
INSERT INTO student SET student.age = 12;
END$$

SP是:
CREATE DEFINER=`root`@`localhost` PROCEDURE `GetDetails`(IN `gage` INT, IN `gname` VARCHAR(255))
BEGIN
INSERT INTO student (name,age) VALUES (gname,gage);
select name from student where id=LAST_INSERT_id();
END

请帮忙解决这个问题。
我更改触发器以将数字添加到学生表stuCode列:
delimiter $$
create trigger genCode AFTER INSERT on student for each row

BEGIN
declare refno varchar(10);
declare refnonew varchar(10);
select refno=student.stuCode into refno FROM student where student.id=(select MAX(student.id) from student);
if (refno is null) or (refno='') then
    set refnonew='000000001';
    UPDATE student
       SET student.stuCode = refnonew where student.id=LAST_INSERT_id();
end if;
END$$

同样的错误?/为什么??

最佳答案

错误消息已经指出:不应该在修改表时触发的触发器中修改表。在这种情况下,每次有人插入一个学生时,您都会尝试插入一个额外的学生。。。
看来是想给新生定个年龄。为此,您可以使用new变量,该变量指向要插入的记录:

delimiter $$
create trigger genCode BEFORE INSERT on student for each row
BEGIN
  NEW.age = 12;
END$$

MySQL trigger syntax
或者您可以简单地为列设置默认值:
ALTER TABLE student MODIFY COLUMN age INT NOT NULL DEFAULT 12;

MySQL alter table syntax
不过,在我看来,最好不要这样做。并不是每个学生都是12岁,触发器应该只用于执行最重要的业务逻辑。我从十年的经验中知道,像这样的触发器会使将来的维护变得很困难,因为在某些时候,您希望删除此默认值,而代码将在意外的地方中断。
如果您想要这样的特性,最好声明一个默认年龄(12岁),并在您的UI中预先填充它。

关于mysql - 为什么不能插入到由同一表的触发器调用的SP中的表?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46391471/

10-11 02:47
查看更多