首页 > 解决方案 > MariaDB:插入后触发器不断出现语法错误

问题描述

我有两张桌子。表vitamin包含列vitamin_nameprice。表vitamin_variety包含列price_varietyprice_variety_extreme。我想创建一个 AFTER INSERT 触发器,它将插入priceof vitaminif vitamin_namecontains extremeintoprice_variety_extreme和 not contains extremeinto的值price_variety

这就是我的意思,如果我将它插入vitamin,价格将被输入vitamin_variety

table = vitamin
+----------------+-------+
|  vitamin_name  | price |
+----------------+-------+
| extreme pill 1 |    10 |
| pill 1         |     5 |
| extreme pill 2 |    20 |
| pill 2         |    10 |
+----------------+-------+
 table = vitamin_variety
+---------------+-----------------------+
| price_variety | price_variety_extreme |
+---------------+-----------------------+
|             5 |                    10 |
|            10 |                    20 |
+---------------+-----------------------+

我的查询不断收到语法错误。它一直在说

#1064 - 您的 SQL 语法有错误;检查与您的 MariaDB 服务器版本相对应的手册,以在第 5 行的 '' 附近使用正确的语法

怎么了?

create trigger vitamin_ain after insert on vitamin
for each ROW
if vitamin.vitamin_name like 'extreme%' then 
    update vitamin_variety 
    set price_variety_extreme = new.price_variety_extreme;
else if vitamin.vitamin_name not like 'extreme%' then 
    update vitamin_variety
    set price_variety = new.price_variety;
end if;

标签: mariadb

解决方案


存在一些语法问题和其他情况,但触发器内的条件可能类似于以下代码:

首先,(不是对或错)else if 可以简化为else. 如果第一个条件发现极端,则无需反向检查not like极端。(除非一些奇怪的要求需要处理)

当然,如果对您更有意义,请随时保持else if检查原样,但我使用了以下代码:

if new.vitamin_name like 'extreme%' then 
    update vitamin_variety 
    set price_variety_extreme = new.price;
else  
    update vitamin_variety
    set price_variety = new.price;
end if

“语法问题”:

  1. 在 if 条件下,更改vitamin.vitamin_namenew.vitamin. 来自触发器插入操作的列是从 引用的new,而不是表名。
  2. 如果保留您的原件else if,则需要更改第vitamin.vitamin_name1 项中提到的相同参考。
  3. 参考文献new.price_variety_extremenew.price_variety不存在来自维生素插入(这些列不在维生素中),而是new.price存在和其他vitamin列。

“其他情况”:

  • 如果vitamin_variety表中没有任何行,则不会发生更新,因为没有要更新的行。这种情况会使触发器看起来好像没有工作,但触发器没有任何东西可以更新。
  • vitamin_variety使用当前信息无法实现所需的输出。更新会将一个或另一个的所有列设置为最后插入的价格,因为没有唯一的行引用。(没有 WHERE 子句来限制更新哪些行)

这是一些示例交互:

正如提到的第一种情况,vitamin_variety表中没有行,所以我添加了一个:

MariaDB [test]> insert into vitamin_variety (price_variety, price_variety_extreme) values (0, 0);
Query OK, 1 row affected (0.08 sec)

MariaDB [test]> select * from vitamin_variety;
+----+---------------+-----------------------+
| id | price_variety | price_variety_extreme |
+----+---------------+-----------------------+
|  1 |             0 |                     0 |
+----+---------------+-----------------------+
1 row in set (0.00 sec)

然后,将触发器添加到vitamin,插入几行:

MariaDB [test]> insert into vitamin( vitamin_name, price ) values ('pilly 5', 7);
Query OK, 1 row affected (0.10 sec)

MariaDB [test]> insert into vitamin( vitamin_name, price ) values ('extreme pill 5', 3);
Query OK, 1 row affected (0.12 sec)

显示这些插入:

MariaDB [test]> select * from vitamin;
+----+----------------+-------+
| id | vitamin_name   | price |
+----+----------------+-------+
|  8 | pilly 5        |     7 |
|  9 | extreme pill 5 |     3 |
+----+----------------+-------+
2 rows in set (0.00 sec)

vitamin_variety在表格中显示触发的价格更新:

MariaDB [test]> select * from vitamin_variety;
+----+---------------+-----------------------+
| id | price_variety | price_variety_extreme |
+----+---------------+-----------------------+
|  1 |             7 |                     3 |
+----+---------------+-----------------------+
1 row in set (0.00 sec)

=====

编辑:

vitamin_variety鉴于此表结构,实现目标的一种可能方法:

CREATE TABLE `vitamin_variety` (
 `pill_name` varchar(25) NOT NULL,
 `price_variety` int(11) NOT NULL DEFAULT '0',
 `price_variety_extreme` int(11) NOT NULL DEFAULT '0',
 UNIQUE KEY `pill_name` (`pill_name`)
);

然后将vitamin表触发条件更改为:

if new.vitamin_name like 'extreme%' then 
    insert into vitamin_variety (pill_name, price_variety_extreme)
    values (replace(new.vitamin_name, 'extreme ', ''), new.price) 
    on duplicate key update price_variety_extreme = new.price;
else  
    insert into vitamin_variety (pill_name, price_variety)
    values (new.vitamin_name, new.price)
    on duplicate key update price_variety = new.price;
end if

然后根据您的原始vitamin表详细信息运行插入 SQL:

MariaDB [test]> insert into vitamin (vitamin_name, price) values ('extreme pill 1', 10);
Query OK, 1 row affected (0.09 sec)

MariaDB [test]> insert into vitamin (vitamin_name, price) values ('pill 1', 5);
Query OK, 1 row affected (0.16 sec)

MariaDB [test]> insert into vitamin (vitamin_name, price) values ('extreme pill 2', 20);
Query OK, 1 row affected (0.10 sec)

MariaDB [test]> insert into vitamin (vitamin_name, price) values ('pill 2', 10);
Query OK, 1 row affected (0.10 sec)

给出:

MariaDB [test]> select * from vitamin_variety;
+-----------+---------------+-----------------------+
| pill_name | price_variety | price_variety_extreme |
+-----------+---------------+-----------------------+
| pill 1    |             5 |                    10 |
| pill 2    |            10 |                    20 |
+-----------+---------------+-----------------------+
2 rows in set (0.00 sec)

推荐阅读