MariaDB не позволяет правильно использовать СИГНАЛ - PullRequest
0 голосов
/ 11 декабря 2019

Вероятно, связано: Определение триггера MySQL - ошибка 1064

Привет,

Я пытаюсь добавить триггер в свою таблицу пользователей в MariaDB 10.40,10-GA. Предполагается, что пользователь может установить второй почтовый адрес, но этот почтовый адрес не должен совпадать с первым почтовым адресом. Код для данного триггера:

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. И даже просто добавив SET testvar="text"; после BEGIN. Выдает ту же ошибку, только с той новой строкой, что и строка с ошибкой. Я сижу по этому вопросу в течение нескольких часов и не могу найти ничего полезного в Интернете. Согласно Документам этот SQL-код должен быть корректным: https://mariadb.com/kb/en/library/signal/ Между прочим, этот пример кода из вышеупомянутой ссылки также не работает с той же ошибкой:

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;

Любые идеи, чтопроблема может быть?

привет

1 Ответ

1 голос
/ 21 декабря 2019

Обязательно используйте 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)

... и затем проверка информации_схемы:

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)
...