2017-04-14 67 views
0

我有兩個表:warehouseinventory插入時觸發;而不是A做B

CREATE TABLE warehouse (
    bin VARCHAR(6) NOT NULL AUTO_INCREMENT, 
    qty INT 
    PRIMARY KEY(bin) 
); 

CREATE TABLE inventory (
    item INT NOT NULL AUTO_INCREMENT, 
    name VARCHAR(10), 
    PRIMARY KEY(item) 
); 

我想設置一個觸發,使得在inventory任何插入,如果插入不具有唯一的名稱,添加到warehouse否則,適當增加warehouse.qty

如果我行插入inventory

INSERT INTO inventory 
VALUES('', 'hammer"); 

inventory   warehouse 
---------------------------- 
item | name  bin | qty 
---------------------------- 
1 hammer  1  1 

inventory行被添加,而且在warehouse一行。然後添加另一個獨特的行:

INSERT INTO inventory 
VALUES('', 'pliers"); 

inventory   warehouse 
---------------------------- 
item | name  bin | qty 
---------------------------- 
1 hammer  1  1 
2 pliers  2  1 

最後添加第二個錘子。

INSERT INTO inventory 
VALUES('', 'hammer"); 

inventory   warehouse 
---------------------------- 
item | name  bin | qty 
---------------------------- 
1 hammer  1  2 
2 pliers  2  1 

注意當第二「錘」插入發生,新行沒有添加到inventory,而不是warehouse相關行有其qty遞增。

如何在SQL中創建此觸發器?

回答

1

14.1.18 CREATE TABLE Syntax

...

  • 某些屬性並不適用於所有數據類型。 AUTO_INCREMENT僅適用於整數和浮點類型。 DEFAULT不適用於BLOB,TEXT,GEOMETRY和JSON類型。

...

CREATE TABLE warehouse (
    bin VARCHAR(6) NOT NULL AUTO_INCREMENT, -- <- It's not possible 
    qty INT, 
    PRIMARY KEY(bin) 
); 

你可能有一些選擇,有一些注意事項:

  • 如果item列必須嚴格按照序列(AUTO_INCREMENT),你可以在封裝存儲過程INSERT邏輯:

Rextester

mysql> DROP PROCEDURE IF EXISTS `insert_inventory`; 
Query OK, 0 rows affected (0.00 sec) 

mysql> DROP TABLE IF EXISTS `warehouse`, `inventory`; 
Query OK, 0 rows affected (0.00 sec) 

mysql> CREATE TABLE `warehouse` (
    ->  `bin` VARCHAR(6) NOT NULL, 
    ->  `qty` INT DEFAULT 1, 
    ->  PRIMARY KEY(`bin`) 
    ->); 
Query OK, 0 rows affected (0.00 sec) 

mysql> CREATE TABLE `inventory` (
    ->  `item` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, 
    ->  `name` VARCHAR(10), 
    ->  PRIMARY KEY(`item`), 
    ->  UNIQUE KEY(`name`) 
    ->); 
Query OK, 0 rows affected (0.01 sec) 

mysql> CREATE TRIGGER `trg_ai_inventory` AFTER INSERT ON `inventory` 
    -> FOR EACH ROW 
    ->  INSERT INTO `warehouse` (`bin`) 
    ->  VALUES (NEW.`item`); 
Query OK, 0 rows affected (0.00 sec) 

mysql> DELIMITER // 

mysql> CREATE PROCEDURE `insert_inventory`(`_name` VARCHAR(10)) 
    -> BEGIN 
    ->  DECLARE `_item` INT DEFAULT (SELECT `item` 
    ->         FROM `inventory` 
    ->         WHERE `name` = `_name`); 
    ->  IF `_item` IS NULL THEN 
    ->   INSERT INTO `inventory` (`name`) 
    ->   VALUES (`_name`); 
    ->  ELSE 
    ->   UPDATE `warehouse` 
    ->   SET `qty` = `qty` + 1 
    ->   WHERE `bin` = `_item`; 
    ->  END IF; 
    -> END// 
Query OK, 0 rows affected (0.00 sec) 

mysql> DELIMITER ; 

mysql> CALL `insert_inventory`('hammer'); 
Query OK, 1 row affected (0.00 sec) 

mysql> SELECT `item`, `name` 
    -> FROM `inventory`; 
+------+--------+ 
| item | name | 
+------+--------+ 
| 1 | hammer | 
+------+--------+ 
1 row in set (0.00 sec) 

mysql> SELECT `bin`, `qty` 
    -> FROM `warehouse`; 
+-----+------+ 
| bin | qty | 
+-----+------+ 
| 1 | 1 | 
+-----+------+ 
1 row in set (0.00 sec) 

mysql> CALL `insert_inventory`('hammer'); 
Query OK, 1 row affected (0.00 sec) 

mysql> SELECT `item`, `name` 
    -> FROM `inventory`; 
+------+--------+ 
| item | name | 
+------+--------+ 
| 1 | hammer | 
+------+--------+ 
1 row in set (0.00 sec) 

mysql> SELECT `bin`, `qty` 
    -> FROM `warehouse`; 
+-----+------+ 
| bin | qty | 
+-----+------+ 
| 1 | 2 | 
+-----+------+ 
1 row in set (0.00 sec) 

mysql> CALL `insert_inventory`('pliers'); 
Query OK, 1 row affected (0.00 sec) 

mysql> SELECT `item`, `name` 
    -> FROM `inventory`; 
+------+--------+ 
| item | name | 
+------+--------+ 
| 1 | hammer | 
| 2 | pliers | 
+------+--------+ 
2 rows in set (0.00 sec) 

mysql> SELECT `bin`, `qty` 
    -> FROM `warehouse`; 
+-----+------+ 
| bin | qty | 
+-----+------+ 
| 1 | 2 | 
| 2 | 1 | 
+-----+------+ 
2 rows in set (0.00 sec) 

忽略(舉例Rextester):

mysql> DROP TABLE IF EXISTS `warehouse`, `inventory`; 
Query OK, 0 rows affected (0.00 sec) 

mysql> CREATE TABLE `warehouse` (
    ->  `bin` VARCHAR(6) NOT NULL, 
    ->  `qty` INT DEFAULT 1, 
    ->  PRIMARY KEY(`bin`) 
    ->); 
Query OK, 0 rows affected (0.00 sec) 

mysql> CREATE TABLE `inventory` (
    ->  `item` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, 
    ->  `name` VARCHAR(10), 
    ->  PRIMARY KEY(`item`), 
    ->  UNIQUE KEY(`name`) 
    ->); 
Query OK, 0 rows affected (0.00 sec) 

mysql> DELIMITER // 

mysql> CREATE TRIGGER `trg_bi_inventory` BEFORE INSERT ON `inventory` 
    -> FOR EACH ROW 
    -> BEGIN 
    ->  DECLARE `_item` INT DEFAULT (SELECT `item` 
    ->         FROM `inventory` 
    ->         WHERE `name` = NEW.`name`); 
    ->  IF `_item` IS NOT NULL THEN 
    ->   UPDATE `warehouse` 
    ->   SET `qty` = `qty` + 1 
    ->   WHERE `bin` = `_item`; 
    ->  END IF; 
    -> END// 
Query OK, 0 rows affected (0.00 sec) 

mysql> DELIMITER ; 

mysql> CREATE TRIGGER `trg_ai_inventory` AFTER INSERT ON `inventory` 
    -> FOR EACH ROW 
    ->  INSERT INTO `warehouse` (`bin`) 
    ->  VALUES (NEW.`item`); 
Query OK, 0 rows affected (0.01 sec) 

mysql> INSERT IGNORE `inventory` (`name`) 
    -> VALUES ('hammer'); 
Query OK, 1 row affected (0.00 sec) 

mysql> SELECT `item`, `name` 
    -> FROM `inventory`; 
+------+--------+ 
| item | name | 
+------+--------+ 
| 1 | hammer | 
+------+--------+ 
1 row in set (0.00 sec) 

mysql> SELECT `bin`, `qty` 
    -> FROM `warehouse`; 
+-----+------+ 
| bin | qty | 
+-----+------+ 
| 1 | 1 | 
+-----+------+ 
1 row in set (0.00 sec) 

mysql> INSERT IGNORE `inventory` (`name`) 
    -> VALUES ('hammer'); 
Query OK, 0 rows affected (0.00 sec) 

mysql> SELECT `item`, `name` 
    -> FROM `inventory`; 
+------+--------+ 
| item | name | 
+------+--------+ 
| 1 | hammer | 
+------+--------+ 
1 row in set (0.00 sec) 

mysql> SELECT `bin`, `qty` 
    -> FROM `warehouse`; 
+-----+------+ 
| bin | qty | 
+-----+------+ 
| 1 | 2 | 
+-----+------+ 
1 row in set (0.00 sec) 

mysql> INSERT IGNORE `inventory` (`name`) 
    -> VALUES ('pliers'); 
Query OK, 1 row affected (0.00 sec) 

mysql> SELECT `item`, `name` 
    -> FROM `inventory`; 
+------+--------+ 
| item | name | 
+------+--------+ 
| 1 | hammer | 
| 3 | pliers | 
+------+--------+ 
2 rows in set (0.00 sec) 

mysql> SELECT `bin`, `qty` 
    -> FROM `warehouse`; 
+-----+------+ 
| bin | qty | 
+-----+------+ 
| 1 | 2 | 
| 3 | 1 | 
+-----+------+ 
2 rows in set (0.00 sec) 

ON DUPL ICATE KEY UPDATE(示例Rextester):

mysql> DROP TABLE IF EXISTS `warehouse`, `inventory`; 
Query OK, 0 rows affected (0.01 sec) 

mysql> CREATE TABLE `warehouse` (
    ->  `bin` VARCHAR(6) NOT NULL, 
    ->  `qty` INT DEFAULT 1, 
    ->  PRIMARY KEY(`bin`) 
    ->); 
Query OK, 0 rows affected (0.00 sec) 

mysql> CREATE TABLE `inventory` (
    ->  `item` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, 
    ->  `name` VARCHAR(10), 
    ->  `count` INT DEFAULT 1, 
    ->  PRIMARY KEY(`item`), 
    ->  UNIQUE KEY(`name`) 
    ->); 
Query OK, 0 rows affected (0.00 sec) 

mysql> CREATE TRIGGER `trg_ai_inventory` AFTER INSERT ON `inventory` 
    -> FOR EACH ROW 
    ->  INSERT INTO `warehouse` (`bin`) 
    ->  VALUES (NEW.`item`); 
Query OK, 0 rows affected (0.00 sec) 

mysql> CREATE TRIGGER `trg_au_inventory` AFTER UPDATE ON `inventory` 
    -> FOR EACH ROW 
    ->  UPDATE `warehouse` 
    ->  SET `qty` = `qty` + 1 
    ->  WHERE `bin` = OLD.`item`; 
Query OK, 0 rows affected (0.00 sec) 

mysql> INSERT INTO `inventory` (`name`) 
    -> VALUES ('hammer') 
    ->  ON DUPLICATE KEY UPDATE `count` = `count` + 1; 
Query OK, 1 row affected (0.00 sec) 

mysql> SELECT `item`, `name` 
    -> FROM `inventory`; 
+------+--------+ 
| item | name | 
+------+--------+ 
| 1 | hammer | 
+------+--------+ 
1 row in set (0.00 sec) 

mysql> SELECT `bin`, `qty` 
    -> FROM `warehouse`; 
+-----+------+ 
| bin | qty | 
+-----+------+ 
| 1 | 1 | 
+-----+------+ 
1 row in set (0.00 sec) 

mysql> INSERT INTO `inventory` (`name`) 
    -> VALUES ('hammer') 
    ->  ON DUPLICATE KEY UPDATE `count` = `count` + 1; 
Query OK, 2 rows affected (0.00 sec) 

mysql> SELECT `item`, `name` 
    -> FROM `inventory`; 
+------+--------+ 
| item | name | 
+------+--------+ 
| 1 | hammer | 
+------+--------+ 
1 row in set (0.00 sec) 

mysql> SELECT `bin`, `qty` 
    -> FROM `warehouse`; 
+-----+------+ 
| bin | qty | 
+-----+------+ 
| 1 | 2 | 
+-----+------+ 
1 row in set (0.00 sec) 

mysql> INSERT INTO `inventory` (`name`) 
    -> VALUES ('pliers') 
    ->  ON DUPLICATE KEY UPDATE `count` = `count` + 1; 
Query OK, 1 row affected (0.00 sec) 

mysql> SELECT `item`, `name` 
    -> FROM `inventory`; 
+------+--------+ 
| item | name | 
+------+--------+ 
| 1 | hammer | 
| 3 | pliers | 
+------+--------+ 
2 rows in set (0.00 sec) 

mysql> SELECT `bin`, `qty` 
    -> FROM `warehouse`; 
+-----+------+ 
| bin | qty | 
+-----+------+ 
| 1 | 2 | 
| 3 | 1 | 
+-----+------+ 
2 rows in set (0.00 sec) 
相關問題