MySQL触发器:在插入/更新事件上

27

所以我有两个像这样的表格...

ext_words
-------------
| id | word |
-------------
| 1  | this |
-------------
| 2  | that |
-------------
| 3  | this |
-------------

ext_words_count
---------------------
| id | word | count |
---------------------
| 1  | this |   2   |
---------------------
| 2  | that |   1   |
---------------------

我正在尝试创建一个触发器,可以:

  • 在更新ext_words.word时更新ext_words_count.count

更加复杂的是,

  • 当更新ext_words时,如果ext_words.word不存在于ext_words_count中,我希望将其插入到ext_words_count中,并将count设置为1。

我查看了类似的问题:
1. 使用自动增量字段的Before / after insert触发器,和
2. 使用触发器更新另一个数据库中的表
试图将两者结合起来。以下是我的部分代码:

DELIMITER $$
CREATE TRIGGER update_count
AFTER UPDATE ON ext_words
FOR EACH ROW
BEGIN

  UPDATE ext_words_count
    SET word_count = word_count + 1
  WHERE word = NEW.word;

END;
$$
DELIMITER ;

非常感谢任何建议和指引。或者可能有我忽略的其他方法,预先致谢!

更新:
我选择使用两个触发器,一个用于 INSERT,一个用于 UPDATE 因为我对 MySQL 中的条件语句不是很熟悉。

DELIMITER $$
CREATE TRIGGER insert_word AFTER INSERT ON ext_words
  FOR EACH ROW
    BEGIN
      INSERT IGNORE INTO ext_words_count (word) VALUES (NEW.word);
    END;
$$
DELIMITER ;

DELIMITER $$
CREATE TRIGGER update_word AFTER UPDATE ON ext_words
  FOR EACH ROW
    BEGIN
      UPDATE ext_words_count 
      SET word_count = word_count + 1 
      WHERE word = NEW.word;
    END;
$$
DELIMITER ;

插入查询功能良好,但更新查询未更新word_count。在更新查询中是否有我遗漏的内容..?


3
您可能希望查看此内容:MySQL插入和更新均适用的触发器。我的解决方案有效吗?我应该如何改进?请记住,在MySQL中,您不能在调用触发器的同一表上进行更新。 - Grijesh Chauhan
@GrijeshChauhan - 感谢您提供的链接!我无法让您的答案起作用,但这是因为我对MySQL中的条件语句还不熟悉,而不是因为您的解决方案有问题。 - Drewness
我的意思是,当ext_words被更新时,如果单词不在ext_words_count中,我想要插入它并将计数设置为1。否则,如果单词已经在ext_words_count中,就将计数增加1... - Drewness
当然,我明白了。因此,我的查询将无法工作,请稍等... - Grijesh Chauhan
我这里有一个快速问题。如果你正在另一个表中以逗号分隔的形式存储单词,比如“这个,那个”,我们能否在该表上编写触发器来拆分值并将其存储在ext_words和ext_words_count中? - Ujjwal Prajapati
2个回答

38

在Grijesh的完美帮助和他使用条件语句的建议下,我能够得到一个触发器完成两项任务。再次感谢Grijesh。

使用Grijesh的完美帮助和他使用条件语句的建议,我能够得到一个触发器同时执行两项任务。再次感谢Grijesh。

 DELIMITER $$ 
 CREATE TRIGGER update_count AFTER INSERT ON ext_words 
 FOR EACH ROW 
   BEGIN
     IF NOT EXISTS (SELECT 1 FROM ext_words_count WHERE word = NEW.word) THEN
       INSERT INTO ext_words_count (word) VALUES (NEW.word);
   ELSE
       UPDATE ext_words_count SET word_count = word_count + 1 WHERE word = NEW.word;
   END IF;
  END $$    
 DELIMITER;   

1
你用哪种形式调用了DB.exchange函数? - Grijesh Chauhan
2
从没收到过任何人的消息。:( 我只是浏览了一些文章。再次感谢您所有的帮助并指引我去其他网站! - Drewness
2
这个触发器在我的MySQL服务器中非常出色地过滤了冗余插入。 - Kiwi

4

避免使用像count这样的关键字,因为它被SQL方法使用。有时会出现错误,但有时会运行良好。

DELIMITER $$
 CREATE TRIGGER update_count
   AFTER UPDATE ON ext_words
     FOR EACH ROW
       BEGIN

          SELECT count INTO @x FROM ext_words_count LIMIT 1;
          UPDATE ext_words_count
          SET count = @x + 1
          WHERE word = NEW.word;

END;
$$
DELIMITER ;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接