Question

I have a MySQL Trigger I am trying to create, but can't get the syntax right.

The trigger should go through and match a set of keywords against the title of the new post inserted into the database. If it finds a match, it should assign the new post to that bucket and update the buckets set of keywords. If it does not find a match, it should create a new bucket using values from the post. The errors point to the line beginning with IF EXISTS, but I can't figure out what's wrong. Any help would be greatly appreciated. Thanks!


UPDATE: Code has been updated to pull out IF EXISTS, but now I am getting an error starting at the ELSE statement.

delimiter $$

CREATE TRIGGER bucket_trigger_v1 BEFORE INSERT ON posts
FOR EACH ROW
  BEGIN
    set @target = NEW.post_title;
    set @bucket_id_number = '';
    set @bucket_relevance = '';

    SELECT idbuckets, MATCH (keywords) AGAINST (@target) AS score INTO @bucket_id_number, @bucket_relevance FROM buckets WHERE MATCH (keywords) AGAINST (@target) ORDER BY score DESC LIMIT 1;
    IF (@bucket_id_number != '') THEN
      BEGIN
        SET NEW.buckets_idbuckets = @bucket_id_number;
        UPDATE buckets SET keywords = concat(keywords, @target) WHERE idbuckets = @bucket_id_number;
      END
      ELSE
      BEGIN
        INSERT INTO buckets (idbuckets, keywords, creationdate) VALUES (, @target, NEW.postdate);
        SET NEW.bucket_idbuckets = (SELECT LAST_INSERT_ID());
      END
    END IF;
END;

$$
Was it helpful?

Solution 2

MySQL, or at least the version I'm running, can't handle multiple triggers at once. The IF statement doesn't work with BEGIN and END because of this, and so I'll have to find a different solution.

OTHER TIPS

A couple of points to consider:

13.2.9.1. SELECT ... INTO Syntax

An INTO clause should not be used in a nested SELECT because such a SELECT must return its result to the outer context.

19.3.1. Trigger Syntax and Examples

Such a SET statement has no effect in an AFTER trigger because the row change will have already occurred.

UPDATE

The following code creates correctly the trigger. The posts table is created only in order to create the trigger.

/*Table structure for table `posts` */

DROP TABLE IF EXISTS `posts`;

CREATE TABLE `posts` (
  `post_title` VARCHAR(500) DEFAULT NULL,
  `buckets_idbuckets` INT(11) DEFAULT NULL,
  `postdate` DATETIME DEFAULT NULL
) ENGINE=INNODB;

/* Trigger structure for table `posts` */

DELIMITER $$

/*!50003 DROP TRIGGER*/ /*!50032 IF EXISTS */ /*!50003 `bucket_trigger_v1` */$$

CREATE TRIGGER `bucket_trigger_v1` BEFORE INSERT ON `posts`
FOR EACH ROW
BEGIN
    SET @target := new.`post_title`;
    SET @bucket_id_number := '';
    SET @bucket_relevance := '';
    SELECT `idbuckets`, MATCH (`keywords`) AGAINST (@target) AS `score` INTO @bucket_id_number, @bucket_relevance FROM `buckets` WHERE MATCH (`keywords`) AGAINST (@target) ORDER BY `score` DESC LIMIT 1;
    IF (@bucket_id_number != '') THEN
        SET new.`buckets_idbuckets` := @bucket_id_number;
        UPDATE `buckets` SET `keywords` = CONCAT(`keywords`, @target) WHERE `idbuckets` = @bucket_id_number;
    ELSE
        INSERT INTO `buckets` (`keywords`, `creationdate`) VALUES (@target, new.`postdate`);
        SET new.`buckets_idbuckets` := LAST_INSERT_ID();
    END IF;
END$$

DELIMITER ;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top