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
的值
您缺少 BEGIN
和 END
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
。您可能需要还原该更改。
我正在做一个小项目,目前正在建立一个 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
您缺少 BEGIN
和 END
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
。您可能需要还原该更改。