Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create mysql event inside a procedure or trigger?

recently i've been searching for a solution to the following situation:

I have mysql table with structure:

CREATE TABLE IF NOT EXISTS `battles` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`active` tinyint(1) NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
`begindate` datetime NOT NULL,
`enddate` datetime NOT NULL,
PRIMARY KEY (`id`),
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;

Every battle has begindate and enddate. Begindate is datetime of insert and usually enddate is three days later.

I would like to create a mysql event that stops the battle (sets active = 0) at the battle enddate. And i would like this event to be created on insert trigger in the battles table.

There is an related issue with very few answers (here).

They advise:

You should be able to do it using a trigger and the event scheduler:

  • create a trigger on the table that is fired on every update / insert
  • this trigger creates a scheduled event that occurs at the datetime of the row and updates >your second table

I've tried to create such a query but with no success.

DELIMITER |
DROP TRIGGER IF EXISTS battle_create_end|
CREATE TRIGGER battle_create_end AFTER INSERT ON battles
  FOR EACH ROW BEGIN

    CREATE EVENT IF NOT EXISTS CONCAT('battle_end_',NEW.id)
    ON SCHEDULE AT NEW.enddate
    DO
    UPDATE battles SET battles.active = 0 WHERE battles.id = NEW.id;

  END|

DELIMITER ;

The error i get is

1576 - Recursion of EVENT DDL statements is forbidden when body is present

I've tried with different delimiters in the for each row structure with no success either.

If someone can help, please advise.

BR, Ilko

like image 337
kachar Avatar asked Oct 09 '22 07:10

kachar


1 Answers

Sorry brother but from what I have been reading what you are proposing is not possible. I don't think you can create an event with a trigger. Which is a bummer because it would be useful for me as well.

It would however be easier to create the event when the row for each battle is created. Hear is an example of some code I found from a guy explaining how events work.

<?php
// establish database connection and filter incoming data
// ...
// insert blog post with pending status, get id assigned to post
$query = "INSERT INTO blog_posts (id, title, post_text, status) 
VALUES (NULL, :title, :postText, 'pending')";
$stm = $db->prepare($query);
$stm->execute(array(":title" => $title, ":postText" => $text));
$id = $db->lastInsertId();

// is this a future post?
if (isset($_POST["schedule"], $_POST["time"])) {
$scheduleDate = strtotime($_POST["time"]);

$query = "CREATE EVENT publish_:id
ON SCHEDULE AT FROM_UNIXTIME(:scheduleDate)
DO
  BEGIN
    UPDATE blog_posts SET status = 'published' WHERE id = :id;
  END";
$stm = $db->prepare($query);
$stm->execute(array(":id" => $id, ":scheduleDate" => $scheduleDate));
}
// this is not a future post, publish now
else {
$query = "UPDATE blog_posts SET status = 'published' WHERE id = :id";
$stm = $db->prepare($query);
$stm->execute(array(":id" => $id));
}

So basically create the event when you add a battle to the table.

like image 174
DcHerrera Avatar answered Oct 13 '22 09:10

DcHerrera