In dem von Ihnen vorgestellten Szenario ist es relativ einfach zu erreichen, was Sie brauchen.
Das Problem tritt auf, wenn die Tabelle leer ist.
mysql> DELIMITER //
mysql> DROP TABLE IF EXISTS `my_table_name`//
Query OK, 0 rows affected (0,00 sec)
mysql> CREATE TABLE IF NOT EXISTS `my_table_name` (
-> `id` INT UNSIGNED NOT NULL PRIMARY KEY,
-> `name` VARCHAR(25),
-> `tipo` INT UNSIGNED NOT NULL
->)//
Query OK, 0 rows affected (0,00 sec)
mysql> CREATE TRIGGER `first_trigger` BEFORE INSERT ON `my_table_name`
-> FOR EACH ROW
-> BEGIN
-> IF NEW.`tipo` != 100 THEN
-> SET NEW.`tipo` := 0;
-> ELSE
-> SET NEW.`id` := (SELECT `id` FROM `my_table_name` LIMIT 1);
-> END IF;
-> END//
Query OK, 0 rows affected (0,00 sec)
mysql> DELIMITER ;
mysql> INSERT INTO `my_table_name`
-> (`id`, `name`, `tipo`)
-> VALUES
-> (1, 'hello', 0), (2, 'world', 0), (3, 'hello3', 0);
Query OK, 3 rows affected (0,01 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT
-> `id`,
-> `name`,
-> `tipo`
-> FROM
-> `my_table_name`;
+----+--------+------+
| id | name | tipo |
+----+--------+------+
| 1 | hello | 0 |
| 2 | world | 0 |
| 3 | hello3 | 0 |
+----+--------+------+
3 rows in set (0,00 sec)
mysql> INSERT IGNORE `my_table_name`
-> (`id`, `name`, `tipo`)
-> VALUES
-> (4, 'hello1', 100), (5, 'hello5', 50);
Query OK, 1 row affected, 1 warning (0,00 sec)
Records: 2 Duplicates: 1 Warnings: 1
mysql> SHOW WARNINGS;
+---------+------+---------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------+
| Warning | 1062 | Duplicate entry '1' for key 'PRIMARY' |
+---------+------+---------------------------------------+
1 row in set (0,00 sec)
mysql> SELECT
-> `id`,
-> `name`,
-> `tipo`
-> FROM
-> `my_table_name`;
+----+--------+------+
| id | name | tipo |
+----+--------+------+
| 1 | hello | 0 |
| 2 | world | 0 |
| 3 | hello3 | 0 |
| 5 | hello5 | 0 |
+----+--------+------+
4 rows in set (0,00 sec)
UPDATE
Eine weitere Option (egal ob die Tabelle leer ist) ist mit Klausel WITH CHECK OPTION
eine aktualisierbare Ansicht zu verwenden.
mysql> DELIMITER //
mysql> DROP VIEW IF EXISTS `view_my_table_name`//
Query OK, 0 rows affected (0,00 sec)
mysql> DROP TABLE IF EXISTS `my_table_name`//
Query OK, 0 rows affected (0,00 sec)
mysql> CREATE TABLE IF NOT EXISTS `my_table_name` (
-> `id` INT UNSIGNED NOT NULL PRIMARY KEY,
-> `name` VARCHAR(25),
-> `tipo` INT UNSIGNED NOT NULL
->)//
Query OK, 0 rows affected (0,00 sec)
mysql> CREATE VIEW `view_my_table_name` AS
-> SELECT `id`, `name`, `tipo`
-> FROM `my_table_name`
-> WHERE `tipo` != 100
-> WITH LOCAL CHECK OPTION//
Query OK, 0 rows affected (0,01 sec)
mysql> CREATE TRIGGER `first_trigger` BEFORE INSERT ON `my_table_name`
-> FOR EACH ROW
-> BEGIN
-> IF NEW.`tipo` != 100 THEN
-> SET NEW.`tipo` := 0;
-> END IF;
-> END//
Query OK, 0 rows affected (0,00 sec)
mysql> DELIMITER ;
mysql> INSERT INTO `my_table_name`
-> (`id`, `name`, `tipo`)
-> VALUES
-> (1, 'hello', 0), (2, 'world', 0), (3, 'hello3', 0);
Query OK, 3 rows affected (0,00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT
-> `id`,
-> `name`,
-> `tipo`
-> FROM
-> `my_table_name`;
+----+--------+------+
| id | name | tipo |
+----+--------+------+
| 1 | hello | 0 |
| 2 | world | 0 |
| 3 | hello3 | 0 |
+----+--------+------+
3 rows in set (0,00 sec)
mysql> INSERT IGNORE `view_my_table_name`
-> (`id`, `name`, `tipo`)
-> VALUES
-> (4, 'hello4', 100), (5, 'hello5', 50);
Query OK, 1 row affected, 1 warning (0,00 sec)
Records: 1 Duplicates: 0 Warnings: 1
mysql> SHOW WARNINGS;
+---------+------+--------------------------------------------+
| Level | Code | Message |
+---------+------+--------------------------------------------+
| Warning | 1369 | CHECK OPTION failed '_.view_my_table_name' |
+---------+------+--------------------------------------------+
1 row in set (0,00 sec)
mysql> SELECT
-> `id`,
-> `name`,
-> `tipo`
-> FROM
-> `my_table_name`;
+----+--------+------+
| id | name | tipo |
+----+--------+------+
| 1 | hello | 0 |
| 2 | world | 0 |
| 3 | hello3 | 0 |
| 5 | hello5 | 0 |
+----+--------+------+
4 rows in set (0,00 sec)
diese Abfrage würde nicht an erster Stelle funktionieren. 'values values' ist ein flacher Syntaxfehler. –
Ablenkungsfehler – ssgakhal
hier ist ein anderer "SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Fehler';
" – e4c5