MySQL + phpMyAdmin,使用 IF 语句触发语法错误

MySQL + phpMyAdmin, syntax error on trigger with IF statement

我正在做一个小项目,目前正在建立一个 MySQL 数据库。不幸的是,这段代码让我发疯:

CREATE TRIGGER main_db.tg_make_competitor
AFTER UPDATE ON main_db.persons
FOR EACH ROW 
IF (NEW.permissions LIKE '%Competitor%') && (SELECT COUNT(*) FROM main_db.competitors WHERE competitor_id LIKE NEW.person_id) = 0 THEN
    INSERT INTO main_db.competitors(competitor_id)
    VALUES (NEW.person_id);
END IF;

我的想法是,当 table persons 发生更新时,触发器应检查记录是否具有 Competitor(SET 数据类型)的权限以及竞争对手是否Id = NEW.person_id 个不存在 - 创建一个。

对我来说,一切似乎都很好。但是 phpMyAdmin 抛出一个错误:

#1064 - Something is wrong in your syntax near '' in line 6

第六行是这部分:

VALUES (NEW.person_id);

我错过了什么吗?我会很感激任何提示。提前致谢!

编辑:人员和竞争对手表结构:

CREATE TABLE main_db.persons 
(
    person_id INT,
    first_name VARCHAR(32) DEFAULT NULL,
    last_name VARCHAR(32) DEFAULT NULL,
    permissions SET('Standard', 'Competitor', 'Referee', 'Organizer', 'Director') DEFAULT 'Standard',
    FOREIGN KEY (person_id) REFERENCES main_db.accounts(account_id) ON DELETE CASCADE,
    PRIMARY KEY (person_id)
);

CREATE TABLE main_db.competitors 
(
    competitor_id INT,
    club VARCHAR(256) DEFAULT NULL,
    license VARCHAR(32) DEFAULT NULL,
    FOREIGN KEY (competitor_id) REFERENCES main_db.persons(person_id) ON DELETE CASCADE,
    PRIMARY KEY (competitor_id)
);

编辑 2:不幸的是,添加了 BEGIN ... END 的代码也不起作用:/

CREATE TRIGGER tg_make_competitor 
AFTER UPDATE ON persons
FOR EACH ROW
BEGIN
IF (NEW.permissions LIKE '%Competitor%') && (SELECT COUNT(*) FROM competitors WHERE competitor_id LIKE NEW.person_id) = 0 THEN
    INSERT INTO competitors(competitor_id)
    VALUES (NEW.person_id);
END IF;
END

解决方案

感谢 Ergest Basha 和 Luuk 的回答,事实证明问题不在于使用自定义定界符。添加它们之后 - 一切都很顺利。

您的代码中没有 sql 语法错误。我在 db-fiddle 中有 运行 这个,它正在工作:

 create table persons (person_id int,permissions varchar(200));
 create table competitors (competitor_id int);

 CREATE TRIGGER tg_make_competitor
 AFTER UPDATE ON persons
 FOR EACH ROW 
 IF NEW.permissions = '%Competitor%' && (SELECT COUNT(*) FROM competitors WHERE competitor_id LIKE NEW.person_id) = 0 THEN
     INSERT INTO competitors(competitor_id)
     VALUES (NEW.person_id);
 END IF;

db<>fiddle here

请检查persion_id

的值

您缺少 BEGINEND https://dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html

在 MySQL 8.0

上测试
mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.25    |
+-----------+
1 row in set (0.00 sec)

mysql> CREATE TABLE persons
    -> (
    ->     person_id INT,
    ->     first_name VARCHAR(32) DEFAULT NULL,
    ->     last_name VARCHAR(32) DEFAULT NULL,
    ->     permissions SET('Standard', 'Competitor', 'Referee', 'Organizer', 'Director') DEFAULT 'Standard',
    ->     PRIMARY KEY (person_id)
    -> );
Query OK, 0 rows affected (0.78 sec)

mysql>
mysql>
mysql>
mysql> CREATE TABLE competitors
    -> (
    ->     competitor_id INT,
    ->     club VARCHAR(256) DEFAULT NULL,
    ->     license VARCHAR(32) DEFAULT NULL,
    ->     FOREIGN KEY (competitor_id) REFERENCES persons(person_id) ON DELETE CASCADE,
    ->     PRIMARY KEY (competitor_id)
    -> );
Query OK, 0 rows affected (0.52 sec)



mysql> DELIMITER //
mysql>  CREATE TRIGGER tg_make_competitor AFTER UPDATE ON persons
    ->     FOR EACH ROW
    ->     BEGIN
    ->          IF (NEW.permissions LIKE '%Competitor%') && (SELECT COUNT(*) FROM competitors WHERE competitor_id LIKE NEW.person_id) = 0 THEN
    ->                INSERT INTO competitors(competitor_id)
    ->                VALUES (NEW.person_id);
    ->          END IF;
    ->      END//
Query OK, 0 rows affected, 1 warning (0.08 sec)

mysql>  DELIMITER ;

此代码在 PhpMyAdmin 中有效:

DELIMITER //
CREATE TRIGGER test.tg_make_competitor
AFTER UPDATE ON test.persons
FOR EACH ROW 
IF (NEW.permissions LIKE '%Competitor%') && (SELECT COUNT(*) FROM test.competitors WHERE competitor_id LIKE NEW.person_id) = 0 THEN
    INSERT INTO test.competitors(competitor_id)
    VALUES (NEW.person_id);
END IF;
//
DELIMITER ;

它只产生这个警告:

Warning: #1287 '&&' is deprecated and will be removed in a future release. Please use AND instead

注意:我在本地测试时确实将 main_db 更改为 test。您可能需要还原该更改。