sqlmysqlmysql-event

MySql Event with LOOP based on a select statemet


Not too familiar with the coding inside events, but the goal is:

  1. Select the "company_id" field of table "companies". (simple select id from table)
  2. Use the list of step 1 into a loop to fetch data from a custom table: eq: "select fid from table_%id% where..."
  3. Now create a record in another table from data together "insert into resulttable (id, fid) values (%id, %fid)

Then create an event to do this every hour

I'd like to do this without creating a procedure, but might need to.

This is as close as I can get:

DECLARE cur_orgs CURSOR FOR SELECT orgId FROM organizations;  
OPEN cur_orgs;
Reading_Orgs: LOOP
    FETCH cur_orgs INTO _org_id;
    
    DECLARE cur_fids CURSOR FOR SELECT fid FROM organization_+'_org_id';  
    OPEN cur_fids;
    Reading_fids: LOOP
        FETCH cur_fids INTO _fid_id;

        insert into queue(orgId, fid) values (_org_id, _fid_id);
    END LOOP;
    CLOSE cur_fids;

    insert into queue(orgId) values (_org_id);
END LOOP;
CLOSE cur_orgs;

Solution

  • Several comments:

    I tested the following with MySQL 8.2.0:

    CREATE EVENT myevent
    ON SCHEDULE AT current_timestamp + INTERVAL 1 MINUTE
    DO
    BEGIN
        DECLARE org_id BIGINT UNSIGNED;
        DECLARE cur_orgs CURSOR FOR SELECT orgId FROM organizations;
    
        OPEN cur_orgs;
    
        Reading_Orgs: LOOP
            FETCH cur_orgs INTO org_id;
            SET @org_id = org_id;
    
            SET @sql = CONCAT(
              'INSERT INTO queue(orgId, fid)
              SELECT ?, fid FROM organization_', @org_id);
    
            PREPARE stmt FROM @sql;
            EXECUTE stmt USING @org_id;
            DEALLOCATE PREPARE stmt;
    
            INSERT INTO queue(orgId) VALUES (@org_id);
        END LOOP;
        CLOSE cur_orgs;
    END
    

    Things to notice:

    The result:

    mysql> show tables;
    +------------------+
    | Tables_in_test   |
    +------------------+
    | organization_123 |
    | organization_456 |
    | organizations    |
    | queue            |
    +------------------+
    
    mysql> select * from organizations;
    +-------+
    | orgId |
    +-------+
    |   123 |
    |   456 |
    +-------+
    
    mysql> select * from organization_123;
    +------+
    | fid  |
    +------+
    |  123 |
    +------+
    
    mysql> select * from organization_456;
    +------+
    | fid  |
    +------+
    |  456 |
    +------+
    

    ... I wait a minute for the event to execute ...

    mysql> select * from queue;
    +-------+------+
    | orgId | fid  |
    +-------+------+
    |   123 |  123 |
    |   123 | NULL |
    |   456 |  456 |
    |   456 | NULL |
    +-------+------+
    

    I don't know what your purpose is of inserting rows in the queue table in this fashion, but I'll trust you that it makes sense for your application. This answer is only meant to show the syntax for your looping routine, not the wisdom of designing your database as it is.

    To be honest, I find MySQL stored routines so awkward to use, that I would recommend coding your events in some client language outside the database. It would be easier to develop and debug in practically any other language other than the MySQL stored routine language.