【问题标题】:Why is mySQL Trigger not saving?为什么 mySQL 触发器不保存?
【发布时间】:2021-03-24 00:09:40
【问题描述】:

如果已经进行了两个具有相同“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 ;

【问题讨论】:

    标签: mysql sql count triggers sql-insert


    【解决方案1】:

    您希望将计数分配给变量,而您的代码比较它。这需要使用已声明的变量并选择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 以生成错误。

    【讨论】:

    • 感谢您的指正,但是触发后仍然没有显示。
    • @GašperŠtepec:我刚刚更改了答案,并添加了一个 DB Fiddle。
    【解决方案2】:

    BEFORE 触发器中,插入的行不能被触发器中的SELECT count(*) ... 语句“看到”。它在新行插入表之前执行。您可以按照 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 ;
    

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

    【讨论】:

    • 检查了您的解决方案,它也可以正常工作。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    • 2018-06-15
    • 2019-04-06
    • 2017-08-06
    相关资源
    最近更新 更多