MariaDB 不允许正确使用 SIGNAL
MariaDB not allowing to use SIGNAL properly
可能相关:MySQL trigger definition - 1064 error
嗨,
我正在尝试在 MariaDB 10.4.10-GA 中为我的 User-Table 添加触发器。目的是,用户可以设置第二个邮件地址,但该邮件地址不能与第一个邮件地址相同。给定触发器的代码:
CREATE TRIGGER MyValidator
BEFORE INSERT
ON User
FOR EACH ROW
BEGIN
IF NEW.U_Mail LIKE '%_@%_.%' THEN
IF NEW.U_AlternateMail LIKE NEW.U_Mail THEN
SIGNAL SQLSTATE VALUE '45001'
SET MESSAGE_TEXT = 'User - Mail already set';
ELSEIF NEW.U_AlternateMail NOT LIKE '%_@%_.%' THEN
SIGNAL SQLSTATE VALUE '45002'
SET MESSAGE_TEXT = 'User - Not a Mail';
END IF;
ELSE
SIGNAL SQLSTATE VALUE '45000'
SET MESSAGE_TEXT = 'User - Bad Mail in database';
END IF;
END;
MariaDB 告诉我:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 9
这将是 SET
语句。甚至只是在 BEGIN
之后添加一个 SET testvar="text";
。产生相同的错误,只是将新行作为错误行。
我已经在这个问题上坐了几个小时了,在互联网上找不到任何有用的东西。
根据文档,这个 SQL-代码应该是正确的:https://mariadb.com/kb/en/library/signal/
有趣的是,上述 link 中的示例代码也无法使用相同的错误:
CREATE PROCEDURE test_error(x INT)
BEGIN
DECLARE errno SMALLINT UNSIGNED DEFAULT 31001;
SET @errmsg = 'Hello, world!';
IF x = 1 THEN
SIGNAL SQLSTATE '45000' SET
MYSQL_ERRNO = errno,
MESSAGE_TEXT = @errmsg;
ELSE
SIGNAL SQLSTATE '45000' SET
MYSQL_ERRNO = errno,
MESSAGE_TEXT = _utf8'Hello, world!';
END IF;
END;
任何想法,问题可能是什么?
问候
确保在添加触发器、函数或存储过程定义时使用 delimiter
。
不确定您使用的是命令行还是其他工具,例如 workbench 或 phpmyadmin,但两种方式都一样。
我用定界符将你的触发语句粘贴到我的命令行中:
delimiter //
CREATE TRIGGER MyValidator
BEFORE INSERT
ON User
FOR EACH ROW
BEGIN
IF NEW.U_Mail LIKE '%_@%_.%' THEN
IF NEW.U_AlternateMail LIKE NEW.U_Mail THEN
SIGNAL SQLSTATE VALUE '45001'
SET MESSAGE_TEXT = 'User - Mail already set';
ELSEIF NEW.U_AlternateMail NOT LIKE '%_@%_.%' THEN
SIGNAL SQLSTATE VALUE '45002'
SET MESSAGE_TEXT = 'User - Not a Mail';
END IF;
ELSE
SIGNAL SQLSTATE VALUE '45000'
SET MESSAGE_TEXT = 'User - Bad Mail in database';
END IF;
END;
//
当运行时(第一次改数据库后),输出为:
MariaDB [(none)]> use test
Database changed
MariaDB [test]> delimiter //
MariaDB [test]> CREATE TRIGGER MyValidator
-> BEFORE INSERT
-> ON User
-> FOR EACH ROW
-> BEGIN
-> IF NEW.U_Mail LIKE '%_@%_.%' THEN
-> IF NEW.U_AlternateMail LIKE NEW.U_Mail THEN
-> SIGNAL SQLSTATE VALUE '45001'
-> SET MESSAGE_TEXT = 'User - Mail already set';
-> ELSEIF NEW.U_AlternateMail NOT LIKE '%_@%_.%' THEN
-> SIGNAL SQLSTATE VALUE '45002'
-> SET MESSAGE_TEXT = 'User - Not a Mail';
-> END IF;
-> ELSE
-> SIGNAL SQLSTATE VALUE '45000'
-> SET MESSAGE_TEXT = 'User - Bad Mail in database';
-> END IF;
-> END;
-> //
Query OK, 0 rows affected (0.11 sec)
...然后检查 information_schema:
MariaDB [test]> select trigger_schema, event_object_table, action_timing, action_statement from information_schema.triggers where trigger_name = 'MyValidator' \G
*************************** 1. row ***************************
trigger_schema: test
event_object_table: user
action_timing: BEFORE
action_statement: BEGIN
IF NEW.U_Mail LIKE '%_@%_.%' THEN
IF NEW.U_AlternateMail LIKE NEW.U_Mail THEN
SIGNAL SQLSTATE VALUE '45001'
SET MESSAGE_TEXT = 'User - Mail already set';
ELSEIF NEW.U_AlternateMail NOT LIKE '%_@%_.%' THEN
SIGNAL SQLSTATE VALUE '45002'
SET MESSAGE_TEXT = 'User - Not a Mail';
END IF;
ELSE
SIGNAL SQLSTATE VALUE '45000'
SET MESSAGE_TEXT = 'User - Bad Mail in database';
END IF;
END
1 row in set (0.01 sec)
可能相关:MySQL trigger definition - 1064 error
嗨,
我正在尝试在 MariaDB 10.4.10-GA 中为我的 User-Table 添加触发器。目的是,用户可以设置第二个邮件地址,但该邮件地址不能与第一个邮件地址相同。给定触发器的代码:
CREATE TRIGGER MyValidator
BEFORE INSERT
ON User
FOR EACH ROW
BEGIN
IF NEW.U_Mail LIKE '%_@%_.%' THEN
IF NEW.U_AlternateMail LIKE NEW.U_Mail THEN
SIGNAL SQLSTATE VALUE '45001'
SET MESSAGE_TEXT = 'User - Mail already set';
ELSEIF NEW.U_AlternateMail NOT LIKE '%_@%_.%' THEN
SIGNAL SQLSTATE VALUE '45002'
SET MESSAGE_TEXT = 'User - Not a Mail';
END IF;
ELSE
SIGNAL SQLSTATE VALUE '45000'
SET MESSAGE_TEXT = 'User - Bad Mail in database';
END IF;
END;
MariaDB 告诉我:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 9
这将是 SET
语句。甚至只是在 BEGIN
之后添加一个 SET testvar="text";
。产生相同的错误,只是将新行作为错误行。
我已经在这个问题上坐了几个小时了,在互联网上找不到任何有用的东西。
根据文档,这个 SQL-代码应该是正确的:https://mariadb.com/kb/en/library/signal/
有趣的是,上述 link 中的示例代码也无法使用相同的错误:
CREATE PROCEDURE test_error(x INT)
BEGIN
DECLARE errno SMALLINT UNSIGNED DEFAULT 31001;
SET @errmsg = 'Hello, world!';
IF x = 1 THEN
SIGNAL SQLSTATE '45000' SET
MYSQL_ERRNO = errno,
MESSAGE_TEXT = @errmsg;
ELSE
SIGNAL SQLSTATE '45000' SET
MYSQL_ERRNO = errno,
MESSAGE_TEXT = _utf8'Hello, world!';
END IF;
END;
任何想法,问题可能是什么?
问候
确保在添加触发器、函数或存储过程定义时使用 delimiter
。
不确定您使用的是命令行还是其他工具,例如 workbench 或 phpmyadmin,但两种方式都一样。
我用定界符将你的触发语句粘贴到我的命令行中:
delimiter //
CREATE TRIGGER MyValidator
BEFORE INSERT
ON User
FOR EACH ROW
BEGIN
IF NEW.U_Mail LIKE '%_@%_.%' THEN
IF NEW.U_AlternateMail LIKE NEW.U_Mail THEN
SIGNAL SQLSTATE VALUE '45001'
SET MESSAGE_TEXT = 'User - Mail already set';
ELSEIF NEW.U_AlternateMail NOT LIKE '%_@%_.%' THEN
SIGNAL SQLSTATE VALUE '45002'
SET MESSAGE_TEXT = 'User - Not a Mail';
END IF;
ELSE
SIGNAL SQLSTATE VALUE '45000'
SET MESSAGE_TEXT = 'User - Bad Mail in database';
END IF;
END;
//
当运行时(第一次改数据库后),输出为:
MariaDB [(none)]> use test
Database changed
MariaDB [test]> delimiter //
MariaDB [test]> CREATE TRIGGER MyValidator
-> BEFORE INSERT
-> ON User
-> FOR EACH ROW
-> BEGIN
-> IF NEW.U_Mail LIKE '%_@%_.%' THEN
-> IF NEW.U_AlternateMail LIKE NEW.U_Mail THEN
-> SIGNAL SQLSTATE VALUE '45001'
-> SET MESSAGE_TEXT = 'User - Mail already set';
-> ELSEIF NEW.U_AlternateMail NOT LIKE '%_@%_.%' THEN
-> SIGNAL SQLSTATE VALUE '45002'
-> SET MESSAGE_TEXT = 'User - Not a Mail';
-> END IF;
-> ELSE
-> SIGNAL SQLSTATE VALUE '45000'
-> SET MESSAGE_TEXT = 'User - Bad Mail in database';
-> END IF;
-> END;
-> //
Query OK, 0 rows affected (0.11 sec)
...然后检查 information_schema:
MariaDB [test]> select trigger_schema, event_object_table, action_timing, action_statement from information_schema.triggers where trigger_name = 'MyValidator' \G
*************************** 1. row ***************************
trigger_schema: test
event_object_table: user
action_timing: BEFORE
action_statement: BEGIN
IF NEW.U_Mail LIKE '%_@%_.%' THEN
IF NEW.U_AlternateMail LIKE NEW.U_Mail THEN
SIGNAL SQLSTATE VALUE '45001'
SET MESSAGE_TEXT = 'User - Mail already set';
ELSEIF NEW.U_AlternateMail NOT LIKE '%_@%_.%' THEN
SIGNAL SQLSTATE VALUE '45002'
SET MESSAGE_TEXT = 'User - Not a Mail';
END IF;
ELSE
SIGNAL SQLSTATE VALUE '45000'
SET MESSAGE_TEXT = 'User - Bad Mail in database';
END IF;
END
1 row in set (0.01 sec)