【问题标题】:I want a trigger to DELETE from 2 tables in MySQL我想要一个触发器从 MySQL 中的 2 个表中删除
【发布时间】:2011-01-25 21:02:11
【问题描述】:

我有 3 个 MySQL 表(foodappleorange)。

我想从以下位置删除行:

apple(idapple, iduser, name) 
orange(idornge, iduser, name)

当使用一个触发器删除food(iduser, name) 中的一行时?

到目前为止,这是我的触发器:

  CREATE TRIGGER `food_before_delete`

    AFTER DELETE ON `food` 
    FOR EACH ROW 

      DELETE FROM apple, orange 
      WHERE 
      apple.iduser=OLD.iduser and 
      orange.iduser=OLD.iduser

但它不会编译。如何创建一个同时从两个表中删除的触发器?

【问题讨论】:

    标签: mysql triggers sql-delete


    【解决方案1】:

    也许更简单一些?

    DELETE f,a,o FROM
    food AS f 
    LEFT JOIN apple AS a USING (iduser)
    LEFT JOIN orange AS o USING (iduser)
    WHERE f.name = ...
    

    不需要触发器。

    【讨论】:

      【解决方案2】:

      使用触发器一次从两个表中删除:

      触发器用于强制表中的数据完整性。您可以使用触发器一次从任意数量的表中删除。

      在初始化触发器之前,我们需要临时更改mysql分隔符操作符,因为触发器使用分号;操作符来指定触发器内的多个sql命令。

      第 1 步更改当前分隔符:

      delimiter $$
      

      第 2 步创建触发器:

      CREATE TRIGGER `blog_before_delete`     
        AFTER DELETE ON `blog`     
        FOR EACH ROW     
      BEGIN
        DELETE FROM blog_tags where blogid = OLD.id;
        DELETE FROM blog_comments where blogid = OLD.id;
      END
      $$
      

      第 3 步恢复之前的分隔符:

      delimiter ;
      

      说明:

      OLD 是一个内置关键字,指的是我们要删除的博客表行。每当我们删除博客表中的条目时,Mysql 都会运行触发器blog_before_delete。如果触发器失败,则删除回滚。这有助于确保 Atomicity, Consistency, Isolation, and Durability 在我们的数据库中。

      【讨论】:

        【解决方案3】:
        CREATE TRIGGER `food_before_delete`     
        AFTER DELETE ON `food`     
        FOR EACH ROW     
        begin
          DELETE FROM apple
          WHERE apple.iduser=NEW.iduser;
        
          DELETE FROM orange
          WHERE orange.iduser=NEW.iduser;
        end
        

        删除语句可能需要 OLD.iduser 而不支持 NEW.iduser。检查您的手册。

        【讨论】:

        • 1054 - 'where 子句'中的未知列 'OLD.iduser'
        • 我认为 NEWOLD 别名仅在 BEFORE 触发器中可用
        • 删除可能需要 NEW 并且不支持 OLD。 - 我将编辑答案以反映这一点。
        • 我怀疑:OLD.col_name refers to a column of an existing row before it is updated or deleted. NEW.col_name refers to the column of a new row to be inserted or an existing row after it is updated.
        • @Mchl 感谢“只有 OLD.col_name 在您执行已删除的过程或触发器时删除一行时才有效”
        【解决方案4】:

        我忘记了触发器中的 BEGINEND 块。你必须像这样按顺序从表中删除:

        CREATE TRIGGER `food_before_delete`     
          AFTER DELETE ON `food`     
          FOR EACH ROW     
        BEGIN
          DELETE FROM apple
          WHERE apple.iduser=NEW.iduser;
        
          DELETE FROM orange
          WHERE orange.iduser=NEW.iduser; 
        END
        

        【讨论】:

        • DELETE 触发器中没有新行
        【解决方案5】:

        创建一个触发器删除两个表的MySQL演练:

        1.登录:

        el@apollo:~$ mysql -u root -p
        Enter password: 
        mysql> use your_database;
        Database changed
        

        2。创建一些测试表并插入行:

        mysql> create table derp(derp1 INT);
        Query OK, 0 rows affected (0.02 sec)
        
        mysql> create table foo(foo1 INT);
        Query OK, 0 rows affected (0.02 sec)
        
        mysql> create table bar(bar1 INT);
        Query OK, 0 rows affected (0.02 sec)
        
        mysql> insert into derp values (1);
        Query OK, 1 row affected (0.01 sec)
        
        mysql> insert into foo values (1);
        Query OK, 1 row affected (0.00 sec)
        
        mysql> insert into bar values (1);
        Query OK, 1 row affected (0.00 sec)
        

        3.触发:

        mysql> delimiter //
        mysql> create trigger delete_foo_and_bar_when_derp_is_deleted
            -> after delete on derp
            -> for each row
            -> begin
            -> delete from foo where foo1=OLD.derp1;
            -> delete from bar where bar1=OLD.derp1;
            -> end//
        Query OK, 0 rows affected (0.02 sec)
        

        4.查看表是否存在并且所有三个都已填充。

        mysql> delimiter ;
        mysql> select * from derp;
        +-------+
        | derp1 |
        +-------+
        |     1 |
        +-------+
        1 row in set (0.00 sec)
        
        mysql> select * from foo;
        +------+
        | foo1 |
        +------+
        |    1 |
        +------+
        1 row in set (0.00 sec)
        
        mysql> select * from bar;
        +------+
        | bar1 |
        +------+
        |    1 |
        +------+
        1 row in set (0.00 sec)
        

        5.从derp中删除

        mysql> delete from derp where derp1 = 1;
        Query OK, 1 row affected (0.01 sec)
        

        6.看到 derp、foo 和 bar 现在是空的:

        mysql> select * from derp;
        Empty set (0.00 sec)
        
        mysql> select * from foo;
        Empty set (0.00 sec)
        
        mysql> select * from bar;
        Empty set (0.00 sec)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-02
          • 1970-01-01
          • 2012-07-28
          • 1970-01-01
          • 2021-11-10
          相关资源
          最近更新 更多