Mysql Before Insert Trigger SET fails
I have fairly simple basic table which I will populate with CHAR(4) primary keys.
These values are selected from a chars table with a subquery.
I want to set up a BEFORE INSERT query so that each time I INSERT a new record from PHP, the id field should get the generated CHAR(4) from subquery.
"ASDF","This is body text", "1970-01-01 01:01:01"
so on.
I'm pulling my hair out with this trigger.
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 ch开发者_开发知识库ars AS c
JOIN chars AS d
ORDER BY RAND()
LIMIT 1);
END
|
Here follows the table structure of messages
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;
And the trick chars table I have found within another answer, which is used for CHAR(4) randomness
CREATE TABLE IF NOT EXISTS `chars` (
`val` char(1) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
What does this have to do with privileges?
EDIT Here's the new error code
#1227 - Access denied; you need the SUPER privilege for this operation
#1227 - Access denied; you need the SUPER privilege for this operation
means that to execute create trigger
you must have SUPER
privilege. Login as user who has such permission and re-run your query.
Some side notices.
The trigger you are creating will not probably work as you want: you cannot just write INSERT INTO messages(body, created) VALUES(some_text, some_datetime)
, you will have to do INSERT INTO messages(id, body, created) VALUES('text', some_text, some_datetime);
(note, you provide a value for 'id' which will be changed by your trigger); otherwise you will have 'Field id doesn't have a default value error' since mysql checks not null constraint before launching your trigger.
Finally, the value of your primary key is random; it does not mater for MyISAM tables, but if you later decide to switch to INNODB engine, you will have performance issues.
Edit: It seems all the linked examples use //
for the delimiter instead of |
. You might want to try that and see if it works better.
Edit 2: If you are running this in PHPMyAdmin from cPanel, you need to control the Delimiter from the little text box Delimeter option below the SQL query window, not by the DELIMETER
command which it seems to ignore.
Also, as I was looking through examples, it seems you need to reset the DELIMITER
back to ;
at the end of the trigger definition, or it seems to remain globally as |
and messes up the future queries, including the contents of the trigger itself when it runs:
END
|
DELIMITER ;
精彩评论