Insert into same table trigger mysql

后端 未结 4 1323
眼角桃花
眼角桃花 2020-12-12 03:35

I need to insert a discount line into a table everything time a I insert a line into the same table. Now i know that this could end in a endless loop but I have put checks i

4条回答
  •  囚心锁ツ
    2020-12-12 04:11

    I needed to add an additional row to the same table, based on a specific condition on an aggregate of the table and was unable to update my application queries to handle it outside of the database, due to stability lock policy.

    An alternative solution is to utilize Events in MySQL to read a "staging" table that holds the pending changes. This works by eliminating the circular reference that would be caused by the trigger. The event then executes the desired changes, without initiating the trigger, by using a session variable to leave the trigger early. Please modify the event timing to suit your needs, such as EVERY 5 SECOND.

    Staging Table

    CREATE TABLE `table_staging` (
       `id` INT NOT NULL,
       `value` VARCHAR(250) NOT NULL,
       `added` TINYINT(1) NOT NULL DEFAULT '0',
       PRIMARY KEY (`id`)
    );
    

    Trigger

    CREATE TRIGGER `table_after_insert` AFTER INSERT ON `table` FOR EACH ROW 
    tableTrigger: BEGIN
    
        IF @EXIT_TRIGGER IS NOT NULL THEN
            /* do not execute the trigger */
            LEAVE tableTrigger;
        END IF;
    
        /* insert the record into staging table if it does not already exist */
        INSERT IGNORE INTO `table_staging`(`id`, `value`)
        VALUES (NEW.id, 'custom value');
    
    END;
    

    Event

    CREATE EVENT `table_staging_add`
        ON SCHEDULE
            EVERY 1 MINUTE STARTS '2020-03-31 18:16:48'
        ON COMPLETION NOT PRESERVE
        ENABLE
        COMMENT ''
        DO BEGIN
    
        /* avoid executing if the event is currently running */
        IF @EXIT_TRIGGER IS NULL THEN
    
            SET @EXIT_TRIGGER=TRUE;
    
            /* add the values that have not already been updated */
            INSERT INTO table(`value`)
            SELECT 
                ts.value
            FROM table_staging AS ts
            WHERE ts.added = 0;
    
            /* update the records to exclude them on the next pass */
            UPDATE table_staging AS ts
            SET ts.added = 1;
    
            /* alternatively remove all the records from the staging table */
            /* TRUNCATE table_staging; */
    
            /* reset the state of execution */
            SET @EXIT_TRIGGER=NULL;
    
        END IF;
    END;
    
    

    Notes

    Be sure to enable the event scheduler in your MySQL configuration (my.ini on Windows or my.cnf on Linux).

    [mysqld]
    event_scheduler = ON
    

提交回复
热议问题