简体   繁体   English

MySQL触发器删除旧记录并插入新记录

[英]MySQL trigger to delete old record and insert new one

i have a table as below 我有一张桌子,如下

Table name: sda_user_eform_data

ack_no   Name       Description
1        name1     This is name1
2        name2     This is name2
3        name3     This is name3

i have another table sda_user_eform_data_bckup which has exactly the same structure as sda_user_eform_data. 我有另一个表sda_user_eform_data_bckup,它的结构与sda_user_eform_data完全相同。 I want to store only 5 rows(latest rows) in the sda_user_eform_data and whenever the ackno is greater than 5 the old values should be moved to the second(sda_user_eform_data_bckup) table. 我只想在sda_user_eform_data中存储5行(最新行),并且每当ackno大于5时,旧值就应该移到第二个(sda_user_eform_data_bckup)表中。

For this first i have copied all the rows from sda_user_eform_data table to the sda_user_eform_data_bckup table. 首先,我已将sda_user_eform_data表中的所有行复制到sda_user_eform_data_bckup表中。 then i have created the following trigger where the i have checked the ack_no and if its greater than 5 then its deleted the oldest ack_no and insert the new value to the bckup table. 然后我创建了以下触发器,其中我已检查ack_no,如果它大于5,则删除了最早的ack_no,并将新值插入bckup表。

DELIMITER $$
create
  trigger 'copy_eform_data' AFTER INSERT
  on asdb.sda_user_eform_data
  for each row begin
  if (select count(s.ack_no) from asdb.sda_user_eform_data s)>5 then
    delete from asdb.sda_user_eform_data where old.ack_no=(select min(s.ack_no) from asdb.sda_user_eform_data s);
  insert into asdb.sda_user_eform_data_bckup select * from asdb.sda_user_eform_data where ack_no=select max(s.ack_no) from asdb.sda_user_eform_data s;
end$$
DELIMITER ;

I am not able to find out where the trigger went wrong as its not executing. 我无法找出触发器未执行的原因。 Any suggestion is highly welcoming. 任何建议都非常欢迎。

Thanks in advance. 提前致谢。

That's most likely because your trigger doesn't even exist. 这很可能是因为您的触发器甚至不存在。 The problem is here 问题在这里

create
  trigger 'copy_eform_data'

With the single quotes copy_eform_data is a string. 用单引号copy_eform_data来的copy_eform_data是一个字符串。

Have a look at this post: When to use single quotes, double quotes, and backticks? 看一下这篇文章: 什么时候使用单引号,双引号和反引号?

Also you should read up about the NEW and OLD keywords in triggers. 您还应该阅读有关触发器中的NEWOLD关键字的信息。 Your trigger probably never matches a line. 您的触发器可能永远不会匹配一行。

And here 和这里

where ack_no=select max(s.ack_no) from asdb.sda_user_eform_data s

you're missing parantheses. 你缺少了寄生物。

Apart from all that, I didn't really have a deep thought about your logic to be honest, because I don't see a point in your whole question. 除此之外,说实话,我真的没有对您的逻辑进行深入的思考,因为我看不到您提出的整个问题。 Why would you want to have duplicate data? 为什么要有重复的数据? I guess out of performance reasons? 我猜出于性能原因? Have your table indexed appropriately and there should be no problem. 为您的表建立适当的索引,应该没有问题。 And to get the 5 latest entries of your table simply use 并获取表的5个最新条目,只需使用

FROM yourTable
ORDER BY when_was_the_entry_created_or_something DESC 
LIMIT 5

You can have columns like 你可以有像

created timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

to use in your ORDER BY . 在您的ORDER BY And you probably want an index on that column. 您可能希望在该列上建立索引。

I doing some changes in your query. 我在您的查询中做了一些更改。 Revert back if it helps. 如果有帮助,请恢复原状。

DELIMITER $$
create
  trigger 'copy_eform_data' AFTER INSERT
  on asdb.sda_user_eform_data
  for each row begin
  insert into asdb.sda_user_eform_data_bckup 
   select * from asdb.sda_user_eform_data ORDER BY ack_no DESC LIMIT 1
  if (select count(s.ack_no) from asdb.sda_user_eform_data s)>=5 then
    delete from asdb.sda_user_eform_data;  
end$$
DELIMITER ;

But make sure that when you are entering records into "asdb.sda_user_eform_data" after clearing table, "ack_no" should again start from 1 但是请确保在清除表后将记录输入到“ asdb.sda_user_eform_data”中时,“ ack_no”应再次从1开始

I was searching for a solution to create trigger for deleting records and came across your forum. 我在寻找一种解决方案来创建用于删除记录的触发器,并遇到了您的论坛。 However, I know this is over a year post and you've most likely solved the issue, but I would like to try to answer your post. 但是,我知道这是超过一年的帖子,您很可能已经解决了该问题,但是我想尝试回答您的帖子。 I think you need a "End If" before your end $$. 我认为您需要在结束$$前先输入“如果结束”。

So it would be: 因此它将是:

 DELIMITER $$
create
 trigger 'copy_eform_data' AFTER INSERT
 on asdb.sda_user_eform_data
 for each row begin
 if (select count(s.ack_no) from asdb.sda_user_eform_data s)>5 then
 delete from asdb.sda_user_eform_data where old.ack_no=(select min(s.ack_no) from  asdb.sda_user_eform_data s);
 insert into asdb.sda_user_eform_data_bckup select * from asdb.sda_user_eform_data where ack_no=select max(s.ack_no) from asdb.sda_user_eform_data s;
END IF;
end$$
DELIMITER ;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM