你有没有演示这种行为的例子?
以下示例更新row_count_line_items
列中的items
表,从BEFORE TRIGGER
开始,对line_items
表中的行数进行计数。因为它是一个BEFORE TRIGGER
,row_count_line_items
列为零(0)(INSERT
没有在那一刻做):
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> DROP TRIGGER IF EXISTS `line_item_trigger`;
Query OK, 0 rows affected (0.00 sec)
mysql> DROP TABLE IF EXISTS `line_items`, `items`;
Query OK, 0 rows affected (0.01 sec)
mysql> CREATE TABLE IF NOT EXISTS `items` (
-> `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
-> `quantity_sold` int(11) unsigned DEFAULT 0,
-> `row_count_line_items` int,
-> PRIMARY KEY (`id`)
->) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE IF NOT EXISTS `line_items` (
-> `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
-> `item_id` int(11) unsigned DEFAULT NULL,
-> `quantity` int(11) unsigned DEFAULT 1,
-> PRIMARY KEY (`id`),
-> CONSTRAINT `fk` FOREIGN KEY (`item_id`) REFERENCES items (`id`)
->) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO `items` (`id`) VALUES (1);
Query OK, 1 row affected (0.01 sec)
mysql> CREATE TRIGGER `line_item_trigger` BEFORE INSERT ON `line_items`
-> FOR EACH ROW
-> UPDATE `items`
-> SET `quantity_sold` = `quantity_sold` + NEW.`quantity`,
-> `row_count_line_items` = (SELECT COUNT(`id`)
-> FROM `line_items`)
-> WHERE `id` = NEW.`item_id`;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO `line_items` (`item_id`) VALUES (1);
Query OK, 1 row affected (0.01 sec)
mysql> COMMIT;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT `id`, `quantity_sold`, `row_count_line_items`
-> FROM `items`;
+----+---------------+----------------------+
| id | quantity_sold | row_count_line_items |
+----+---------------+----------------------+
| 1 | 1 | 0 |
+----+---------------+----------------------+
1 row in set (0.00 sec)
mysql> SELECT `id`, `item_id`, `quantity`
-> FROM `line_items`;
+----+---------+----------+
| id | item_id | quantity |
+----+---------+----------+
| 1 | 1 | 1 |
+----+---------+----------+
1 row in set (0.00 sec)
见db-fiddle。
如果我们改变了事件AFTER
(AFTER TRIGGER
),然后row_count_line_items
列将有一个(1)(因为,INSERT
已经完成)值:
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> DROP TRIGGER IF EXISTS `line_item_trigger`;
Query OK, 0 rows affected (0.00 sec)
mysql> DROP TABLE IF EXISTS `line_items`, `items`;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE IF NOT EXISTS `items` (
-> `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
-> `quantity_sold` int(11) unsigned DEFAULT 0,
-> `row_count_line_items` int,
-> PRIMARY KEY (`id`)
->) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE IF NOT EXISTS `line_items` (
-> `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
-> `item_id` int(11) unsigned DEFAULT NULL,
-> `quantity` int(11) unsigned DEFAULT 1,
-> PRIMARY KEY (`id`),
-> CONSTRAINT `fk` FOREIGN KEY (`item_id`) REFERENCES items (`id`)
->) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO `items` (`id`) VALUES (1);
Query OK, 1 row affected (0.00 sec)
mysql> CREATE TRIGGER `line_item_trigger` AFTER INSERT ON `line_items`
-> FOR EACH ROW
-> UPDATE `items`
-> SET `quantity_sold` = `quantity_sold` + NEW.`quantity`,
-> `row_count_line_items` = (SELECT COUNT(`id`)
-> FROM `line_items`)
-> WHERE `id` = NEW.`item_id`;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO `line_items` (`item_id`) VALUES (1);
Query OK, 1 row affected (0.08 sec)
mysql> SELECT `id`, `quantity_sold`, `row_count_line_items`
-> FROM `items`;
+----+---------------+----------------------+
| id | quantity_sold | row_count_line_items |
+----+---------------+----------------------+
| 1 | 1 | 1 |
+----+---------------+----------------------+
1 row in set (0.00 sec)
mysql> COMMIT;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT `id`, `item_id`, `quantity`
-> FROM `line_items`;
+----+---------+----------+
| id | item_id | quantity |
+----+---------+----------+
| 1 | 1 | 1 |
+----+---------+----------+
1 row in set (0.00 sec)
见db-fiddle。
你在一个事务中执行多个插入'line_items'吗? –
正如我所知,在他插入新行之前触发器会首先更新您的查询。根据我的经验,这是触发器的工作原理 – Noob
@ilya bursov这只是在每个事务中插入的单个行项目。 –