Mysql Before Insert Trigger SET не удается - PullRequest
1 голос
/ 19 июня 2011

У меня есть довольно простая базовая таблица, которую я буду заполнять первичными ключами CHAR (4).

Эти значения выбираются из таблицы chars с подзапросом.

Я хочу настроить запрос BEFORE INSERT , чтобы каждый раз, когда я INSERT представлял новую запись из PHP, поле id получало сгенерированный CHAR (4) из подзапроса.

"ASDF", "Это основной текст", "1970-01-01 01:01:01"

и т. Д.

Я дергаю себя за волосы этим триггером.

DELIMETER |
CREATE TRIGGER messages_newid 
BEFORE INSERT ON messages
FOR EACH ROW
BEGIN
  SET NEW.id = (SELECT CONCAT(a.val,b.val,c.val,d.val)
    FROM chars AS a
    JOIN chars AS b
    JOIN chars AS c
    JOIN chars AS d
    ORDER BY RAND()
    LIMIT 1);
END
|

Ниже следует структура таблицы из сообщений

CREATE TABLE IF NOT EXISTS `messages` (
  `id` varchar(4) collate utf8_unicode_ci NOT NULL,
  `body` text collate utf8_unicode_ci,
  `created` datetime default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

И уловка chars таблицы, которую я нашел в другом ответе, которыйиспользуется для CHAR (4) случайность

CREATE TABLE IF NOT EXISTS `chars` (
  `val` char(1) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Какое отношение это имеет к привилегиям?

EDIT Вот новый код ошибки

#1227 - Access denied; you need the SUPER privilege for this operation

Ответы [ 2 ]

2 голосов
/ 19 июня 2011
#1227 - Access denied; you need the SUPER privilege for this operation 

означает, что для выполнения create trigger у вас должна быть привилегия SUPER. Войдите в систему как пользователь, у которого есть такое разрешение, и повторите запрос.

Некоторые побочные уведомления.
Триггер, который вы создаете, вероятно, не будет работать так, как вы хотите: вы не можете просто написать INSERT INTO messages(body, created) VALUES(some_text, some_datetime), вам придется делать INSERT INTO messages(id, body, created) VALUES('text', some_text, some_datetime); (обратите внимание, вы предоставляете значение для 'id', которое будет изменяться вашим триггером); в противном случае у вас будет «Идентификатор поля не содержит ошибку значения по умолчанию», поскольку mysql проверяет не нулевое ограничение перед запуском триггера.

Наконец, значение вашего первичного ключа является случайным; это не имеет значения для таблиц MyISAM, но если позднее вы решите переключиться на механизм INNODB, у вас будут проблемы с производительностью.

2 голосов
/ 19 июня 2011

Редактировать: Кажется, что все связанные примеры используют // вместо разделителя |.Вы можете попробовать это и посмотреть, работает ли он лучше.

Edit 2: Если вы запускаете это в PHPMyAdmin из cPanel, вам нужно управлять разделителем из littleтекстовое поле Опция Delimeter под окном запроса SQL, а не команда DELIMETER, которую она, кажется, игнорирует.

Кроме того, поскольку я выглядел - примеры , кажется, вам нужно сбросить DELIMITER обратно на ; в конце определения триггера, или он, похоже, остается глобально как | и портит будущие запросы, включаясодержимое самого триггера при его запуске:

END
|
DELIMITER ;
...