为什么 mySQL 触发器不保存?

Why is mySQL Trigger not saving?

我正在尝试创建一个触发器,如果​​已经进行了两个具有相同“St_Obr”的插入,它会停止插入。它没有显示任何错误,但是当我执行 SQL 脚本时,触发器没有被保存。至少当我执行 SHOW TRIGGERS;

时它没有显示

代码:

DELIMITER //

CREATE TRIGGER ob_limit
BEFORE INSERT ON TUP.Lab FOR EACH ROW
BEGIN
    SELECT @a = COUNT(*)
    FROM TUP.Lab
    WHERE St_Obr = NEW.St_Obr;
    IF (@a > 2) THEN
        SIGNAL SQLSTATE '45000'
        SET MESSAGE_TEXT = 'MAX 2!';
    END IF;
END //
DELIMITER ;

您想将计数分配给变量,而您的代码比较它。这将需要使用声明的变量并选择 into 它。

但是我发现直接在if语句中跳过变量和运行查询更简单:

CREATE TRIGGER ob_limit
BEFORE INSERT ON Lab FOR EACH ROW
BEGIN
    
    IF ((SELECT COUNT(*) FROM Lab WHERE St_Obr = NEW.St_Obr) >= 2) THEN
        SIGNAL SQLSTATE '45000'
        SET MESSAGE_TEXT = 'MAX 2!';
    END IF;

END //

DELIMITER ;

请注意,我将不等式从 > 更改为 >=2:前者允许每个 St_Obr 三行,而后者仅允许 2 行(这似乎是您想要的).

这里有一个Demo on DB Fiddle;您可以注释或取消注释第三个 insert 以生成错误。

BEFORE 触发器中,插入的行不能被触发器中的 SELECT count(*) ... 语句“看到”。它在新行插入 table 之前执行。您可以按照 GMB 的建议将限制降低到 1 或使用 >=。或者您可以将触发器更改为 AFTER 触发器。

CREATE TRIGGER ob_limit
               AFTER INSERT ON Lab
               FOR EACH ROW
BEGIN
 IF (SELECT count(*)
            FROM Lab
            WHERE st_obr = new.st_obr) > 2 THEN
    SIGNAL SQLSTATE '45000'
           SET MESSAGE_TEXT = 'MAX 2!';
  END IF;
END //
DELIMITER ;

(注意你把结果赋值给变量的方式也是错误的,但是不需要变量,直接用子查询比较即可)