如何为总票数增加/减少 1 个数字创建更新触发器

Posted

技术标签:

【中文标题】如何为总票数增加/减少 1 个数字创建更新触发器【英文标题】:how to create a update trigger for Increase/Decrease 1 number to total votes number 【发布时间】:2015-08-10 13:15:53 【问题描述】:

我有两张桌子:

// posts
+----+---------+-----------+-------------+
| id |  title  |  content  | total_votes |
+----+---------+-----------+-------------+
| 1  |  title1 |  content1 |     3       |
| 2  |  title2 |  content2 |     2       |
+----+---------+-----------+-------------+

// votes
+----+---------+-------+
| id | id_post | value |
+----+---------+-------+
| 1  |     1   |   1   |
| 2  |     1   |   1   |
| 3  |     1   |   1   |
| 4  |     2   |  -1   |
| 5  |     2   |   1   |
| 6  |     2   |   1   |
| 7  |     2   |   1   |
+----+---------+-------+

现在我需要一个触发器来更新posts.total_votes。当一个用户给出新的投票(1或-1)时,这将是votes表中的新行,所以我想在插入votes表后,自动触发更新total_votes的数量并应用新的投票。有可能吗?

例如:

If new votes.values == 1  then posts.totla_votes++;
If new votes.values == -1 then posts.total_votes--;

编辑:

我有两个帖子表(posts_A | posts_B)。我还在投票表上添加了一个新列,其中包含表的名称。所以我需要触发器更新相应的表。像这样:update new.table_name ... 而不是 update posts ...

// posts_A
+----+---------+-----------+-------------+
| id |  title  |  content  | total_votes |
+----+---------+-----------+-------------+
| 1  |  title1 |  content1 |     2       |
| 2  |  title2 |  content2 |    -1       |
+----+---------+-----------+-------------+

// posts_B
+----+---------+-----------+-------------+
| id |  title  |  content  | total_votes |
+----+---------+-----------+-------------+
| 1  |  title1 |  content1 |     1       |
| 2  |  title2 |  content2 |     3       |
+----+---------+-----------+-------------+

// votes
+----+---------+-------+------------+
| id | id_post | value | table_name |
+----+---------+-------+------------+
| 1  |     1   |   1   |   post_A   |
| 2  |     1   |   1   |   post_A   |
| 3  |     1   |   1   |   post_B   |
| 4  |     2   |  -1   |   post_A   |
| 5  |     2   |   1   |   post_B   |
| 6  |     2   |   1   |   post_B   |
| 7  |     2   |   1   |   post_B   |
+----+---------+-------+------------+

这是我的尝试,但我不知道为什么它不起作用? :

delimiter //
create trigger total_votes_count_upd after update on votes
for each row
begin
 if (new.value == 1) then
   update new.table_name set total_votes = total_votes+1 
   where id = new.id_post;
 elseif (new.value == -1) then
   update new.table_name set total_votes = total_votes-1 
   where id = new.id_post;
 end if;
end;//

delimiter //

实际上我直接替换了new.table_name而不是表名(posts)。但正如我所说,它不起作用。我该如何解决?

【问题讨论】:

【参考方案1】:

是的,您需要为此创建一个after insert trigger

delimiter //
create trigger total_votes_count after insert on votes
for each row
begin
 if (new.value == 1) then
   update posts set total_votes = total_votes+1 
   where id = new.id_post;
 elseif (new.value == -1) then
   update posts set total_votes = total_votes-1 
   where id = new.id_post;
 end if;
end;//

delimiter //

为了处理更新,一切都保持不变,只是你需要另一个触发器

delimiter //
    create trigger total_votes_count_upd after update on votes
    for each row
    begin
     if (new.value == 1) then
       update posts set total_votes = total_votes+1 
       where id = new.id_post;
     elseif (new.value == -1) then
       update posts set total_votes = total_votes-1 
       where id = new.id_post;
     end if;
    end;//

    delimiter //

由于您有 2 个 post 表,因此您需要在 if 条件中使用它

delimiter //
create trigger total_votes_count after insert on votes
for each row
begin
 if (new.value == 1) then
   if (new.table_name == 'post_A') then 
     update posts_A set total_votes = total_votes+1 
     where id = new.id_post;
   else
     update posts_B set total_votes = total_votes+1 
     where id = new.id_post;
   end if;
 elseif (new.value == -1) then
   if (new.table_name == 'post_A') then
      update posts_A set total_votes = total_votes-1 
      where id = new.id_post;
   else
      update posts_B set total_votes = total_votes-1 
      where id = new.id_post;
   end if ; 
 end if;
end;//

delimiter //

对更新触发器执行相同操作。

【讨论】:

ow tnx :-) !因为我不太了解触发器,所以我有三个问题。 1.new.value中的new是什么?它是触发器中定义(固定)的词吗? 2. 我可以用else 代替elseif 吗? 3.代码开头和结尾的delimiter //是什么? tnx 再次 1. delimiter // 是设置与默认 ; 不同的分隔符,以便执行整个触发代码,而不是在第一次出现 ; 时停止执行 2. 您可以使用 else 但这也意味着 -1,0,etc other than 1 如果您确定该表将始终具有1 and -1 那么是的else 应该完成这项工作.. 3. new 是插入/更新后引用新值的关键字,因此这里new.id_post 将是值插入完成后的id_post 我明白了,+1 投票并接受您的解决方案作为我的答案... :) 我认为where post.id = new.id_post; 更好,对于我的 mysql 版本 where id = new.id_post;不会工作。 对于更新,您需要另一个触发器,只需添加到答案中。

以上是关于如何为总票数增加/减少 1 个数字创建更新触发器的主要内容,如果未能解决你的问题,请参考以下文章

如何为 Google AdWords API 的广告组增加/减少移动出价标准?

如何为 Google 表格中单列中的每个值设置数字格式取决于值?

如何为没有已知列的 PostgreSQL 视图编写通用更新触发器?

SQL Server数据库多表关联如何更新?

RoR 投票系统。如何计算票数、反对票和总票数?

如果父元素也有鼠标悬停,如何为子元素触发鼠标悬停事件?