【问题标题】:Mysql Before Insert Trigger SET failsMysql Before Insert Trigger SET失败
【发布时间】:2011-09-18 00:27:53
【问题描述】:

我有一个相当简单的基本表,我将用 CHAR(4) 主键填充它。

这些值是从带有子查询的 chars 表中选择的。

我想设置一个 BEFORE INSERT 查询,以便每次我从 PHP INSERT 一条新记录时,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
|

下面是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;

我在另一个答案中找到的技巧 chars 表用于 CHAR(4) 随机性

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

这和特权有什么关系?

编辑这是新的错误代码

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

【问题讨论】:

    标签: mysql select triggers insert


    【解决方案1】:
    #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”值将由您的触发器更改);否则您将出现“字段 id 没有默认值错误”,因为 mysql 在启动触发器之前会检查非空约束。

    最后,你的主键值是随机的;它不适用于 MyISAM 表,但如果您稍后决定切换到 INNODB 引擎,则会遇到性能问题。

    【讨论】:

      【解决方案2】:

      编辑:似乎所有链接的示例都使用// 作为分隔符而不是|。您可能想尝试一下,看看它是否效果更好。

      编辑 2: 如果您从 cPanel 在 PHPMyAdmin 中运行它,您需要从 SQL 查询窗口下方的 little text box Delimeter option 控制分隔符,而不是通过看起来的 DELIMETER 命令忽略。

      另外,因为我是looking through examples,看来您需要在触发器定义的末尾将DELIMITER 重置回;,或者它似乎在全局范围内保持为@987654331 @ 并搞乱未来的查询,包括触发器运行时的内容:

      END
      |
      DELIMITER ;
      

      【讨论】:

      • #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMETER | CREATE TRIGGER messages_newid BEFORE INSERT ON messages FOR EACH ' at line 1 并没有改变这种情况。
      • @Cengiz:嗯,我链接的所有示例都使用// 作为分隔符。也许它更有效,你可以试试它而不是|
      • @mellamokb 将分隔符更改为 // 给出了另一个错误,例如 ERROR: Unknown Punctuation String @ 11 STR: // SQL: 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) ....... ORDER BY RAND() LIMIT 1);DELIMETER //.......
      • @Cengiz:另外,请注意我上面的编辑。如果您确实使用DELIMETER |,我认为您必须使用之前的分隔符; 标记该语句的结尾,如下所示:DELIMETER |; ;。例如,请参见此处:stackoverflow.com/questions/1267172/mysql-delimiter-error。试试看,让我知道结果。
      • @mellamokb 这只是使分隔符成为 2 个字符 |; 因此,是 DELIMETER 方法的错误使用。
      猜你喜欢
      • 2011-03-16
      • 2017-03-24
      • 2011-03-13
      • 1970-01-01
      • 1970-01-01
      • 2020-11-08
      • 1970-01-01
      • 1970-01-01
      • 2018-04-05
      相关资源
      最近更新 更多