问题
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. 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.
For this first i have copied all the rows from sda_user_eform_data table to the sda_user_eform_data_bckup table. 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.
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.
回答1:
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.
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. 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
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
. And you probably want an index on that column.
回答2:
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
回答3:
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 ;
来源:https://stackoverflow.com/questions/17963694/mysql-trigger-to-delete-old-record-and-insert-new-one