创建更新后触发器后无法更新表

Ric*_*Roy 1 mysql trigger stored-procedures

我有一张这样的桌子

/*Table: pageprivilege*/
------------------------

/*Column Information*/
----------------------

FIELD   TYPE              COLLATION          NULL    KEY     DEFAULT  Extra           PRIVILEGES                       COMMENT
------  ----------------  -----------------  ------  ------  -------  --------------  -------------------------------  -------
id      INT(10) UNSIGNED  (NULL)             NO      PRI     (NULL)   AUTO_INCREMENT  SELECT,INSERT,UPDATE,REFERENCES         
pageid  VARCHAR(20)       latin1_swedish_ci  YES             (NULL)                   SELECT,INSERT,UPDATE,REFERENCES         
roleid  TINYINT(4)        (NULL)             YES             (NULL)                   SELECT,INSERT,UPDATE,REFERENCES         
ad      TINYINT(1)        (NULL)             YES             0                        SELECT,INSERT,UPDATE,REFERENCES         
ed      TINYINT(1)        (NULL)             YES             0                        SELECT,INSERT,UPDATE,REFERENCES         
dl      TINYINT(1)        (NULL)             YES             0                        SELECT,INSERT,UPDATE,REFERENCES         
rd      TINYINT(1)        (NULL)             YES             0                        SELECT,INSERT,UPDATE,REFERENCES         
st      TINYINT(1)        (NULL)             YES             0                        SELECT,INSERT,UPDATE,REFERENCES   
Run Code Online (Sandbox Code Playgroud)

我有一个条件,如果行被更新,这样

ad、ed、dl、rd 都设置为 0 那么 st 的值也自动更改为 0

为此我写了一个程序

CREATE
    /*[DEFINER = { user | CURRENT_USER }]*/
    PROCEDURE `smsdev`.`update_priv`()
    /*LANGUAGE SQL
    | [NOT] DETERMINISTIC
    | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
    | SQL SECURITY { DEFINER | INVOKER }
    | COMMENT 'string'*/
    BEGIN

     UPDATE pageprivilege SET st=0 WHERE ad = 0 AND ed =0 AND dl =0 AND rd = 0;

    END$$

DELIMITER ;  
Run Code Online (Sandbox Code Playgroud)

并添加了一个触发器,该触发器在表更新后被调用并调用如下过程

DELIMITER $$

USE `smsdev`$$

DROP TRIGGER /*!50032 IF EXISTS */ `pageprivilege_update`$$

CREATE
    /*!50017 DEFINER = 'smsdev'@'%' */
    TRIGGER `pageprivilege_update` AFTER UPDATE ON `pageprivilege` 
    FOR EACH ROW BEGIN
     CALL update_priv();
END;
$$

DELIMITER ;
Run Code Online (Sandbox Code Playgroud)

问题是每当我对 4 个字段中的任何一个进行任何更新时,ad, ed, dl, rd我都会收到此错误

无法更新存储函数/触发器中的表“pageprivilege”,因为它已被调用此存储函数/触发器的语句使用。

我是使用触发器和存储过程的新手,我确实读到从内部触发器触发程序是一个坏主意,但这对我来说就像是一个想法测试,所以如果你能容忍我并帮助我解决这个问题-ish 代码将是 gr8。

小智 5

这是正确的,您不能更新执行触发器的同一个表,但是如果您使用,before update您可以st通过检查条件将其设置为 0

DELIMITER $$

USE `smsdev`$$

DROP TRIGGER /*!50032 IF EXISTS */ `pageprivilege_update`$$

CREATE
    /*!50017 DEFINER = 'smsdev'@'%' */
    TRIGGER `pageprivilege_update` BEFORE UPDATE ON `pageprivilege` 
    FOR EACH ROW 
    BEGIN
     if (new.ad = 0 AND new.ed =0 AND new.dl =0 AND new.rd = 0) then
       set new.st=0 ;
     end if;
END;
$$

DELIMITER ;
Run Code Online (Sandbox Code Playgroud)