如何在表上创建插入触发器?

时间:2014-06-18 16:12:18

标签: mysql sql triggers

我有表warehouse

++++++++++++++
+ id + count +
++++++++++++++
+ 1  + 10    +
++++++++++++++
+ 10 + 100   +
++++++++++++++
+ 3  + 200   +
++++++++++++++

我想创建触发器,因此如果我插入表中存在的值的数据,则此行的计数将被更新,并且不会插入新行。如果表中没有包含此ID的数据,则必须添加新行。

预期结果:

查询后:

INSERT INTO Warehouse (id, count) VALUES (1, 15);

仓库表内容将是:

++++++++++++++
+ id + count +
++++++++++++++
+ 1  + 25    +
++++++++++++++
+ 10 + 100   +
++++++++++++++
+ 3  + 200   +
++++++++++++++

在此查询之后:

INSERT INTO Warehouse (id, count) VALUES (8, 11);

仓库内容将变为:

++++++++++++++
+ id + count +
++++++++++++++
+ 1  + 25    +
++++++++++++++
+ 10 + 100   +
++++++++++++++
+ 3  + 200   +
++++++++++++++
+ 8  + 11    +
++++++++++++++

之后:

INSERT INTO Warehouse (id, count) VALUES (3, 5);

仓库内容将变为:

++++++++++++++
+ id + count +
++++++++++++++
+ 1  + 25    +
++++++++++++++
+ 10 + 100   +
++++++++++++++
+ 3  + 205   +
++++++++++++++
+ 8  + 11    +
++++++++++++++

我正在使用MySQL 5.1。

更新

如果我使用这种方法在Warehouse表中插入内容怎么办?

INSERT INTO 
    Warehouse
    (
        count,
        id
    )
    SELECT 
        count,
        id
    FROM 
        ShopOrderGoods
    WHERE 
        order_id = 1

是否有可能通过这种方法获得我想要的行为?

1 个答案:

答案 0 :(得分:3)

MySQL不支持INSTEAD OF触发器;也就是说,使用触发器无法做到这一点。

假设id列是表格的PRIMARY KEY(或者至少是表格上的UNIQUE KEY),您可以使用ON DUPLICATE KEY形式的{ {1}}语句来实现您描述的行为。

例如:

INSERT

MySQL将尝试插入,如果抛出一个"重复键"异常,然后将尝试UPDATE操作。在上面的示例中,INSERT INTO Warehouse (id, count) VALUES (1, 15) ON DUPLICATE KEY UPDATE count = count + VALUES(`count`); 列的当前值将为该列添加新值(在插入的VALUES子句中)。

(注意:如果count列的当前值为NULL,或者插入的值为NULL,则将为count列分配NULL。如果要处理NULL值为零,那么您可以增强表达式来处理这些情况:

count

NB 如果表中有另一列具有ON DUPLICATE KEY UPDATE `count` = IFNULL(`count`,0) + IFNULL(VALUES(`count`),0) 属性,则每次插入尝试都会增加表的自动增量,包括重复键异常的那些扔了。

<强>更新

(基于问题的更新)

AUTO_INCREMENT形式的INSERT将与ON DUPLICATE KEY一起使用,就像INSERT ... SELECT一样。

INSERT ... VALUES

(在我的回答的第一个示例中,我在列表中添加了列名&#34;计数&#34;因为我不确定 INSERT INTO Warehouse (count,id) SELECT s.count, s.id FROM ShopOrderGoods s WHERE s.order_id = 1 ON DUPLICATE KEY UPDATE `Warehouse`.`count` = `Warehouse`.`count` + VALUES(`count`); 是否为一个保留字。它看起来像一个保留字,但我没有检查列表。在最后一个例子中,我没有用反引号括起列名。我不能用#&# 34;计算&#34;作为列名或别名。) 使用从不名字)