1

Within a mysql trigger, I need to loop through a comma-separated list and perform a query for each item on the list

DELIMITER $$
DROP trigger IF EXISTS my_trigger $$
CREATE TRIGGER my_trigger AFTER UPDATE ON my_table
 FOR EACH ROW BEGIN 
    SET @id = NEW.id;
    SET @item_str = NEW.item_str; -- This is a comma separated list of integers like "34,1,200,99"
    

    /*DYNAMIC SECTION*/
    SET @item_list = CONCAT('''',REPLACE(REPLACE(@item_str ,' ',''),',',QUOTE(',')),'''');

    SET @list_stub = REPLACE(@item_list,',','');
    SET @list_count = LENGTH(@item_list) - LENGTH(@list_stub) + 1;
    
    -- Loop through list of items
    SET @x = 0;
    WHILE @x < @list_count DO
        SET @x = @x + 1;
        SET @sql = CONCAT('SELECT ELT(',@x,',',@item_list,') INTO @item');
        PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
        
        SET @sql = CONCAT('INSERT IGNORE INTO new_table (id, item) VALUES(', @id, ',', @item, ')' );
        PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
    END WHILE;

END $$
DELIMITER ;

This gives me the error: ERROR 1336 (0A000): Dynamic SQL is not allowed in stored function or trigger

Since the "Dynamic Section" had worked well in a stored procedure, I tried moving that portion to a separated procedure, then called it from this trigger:

Same error!

The closest question I found on the subject (Loop in trigger with comma separated values mysql) looked very lean and unhelpful. The link included in that answer is infact dead. In any case, it uses creating of temporary table which I suspect would throw up permission issues with this user.

Is there at least a workaround? How can I loop through this list and perform a query with each value?

Ifedi Okonkwo
  • 3,108
  • 4
  • 25
  • 44
  • Show an example of CSV values list (2-3 values enough) and the query text which must be executed for one of these values. – Akina Sep 09 '20 at 08:01
  • Which version of MySQL? – Nick Sep 09 '20 at 08:18
  • Basically, you shouldn't be using comma (or otherwise) delimited data. See https://stackoverflow.com/questions/3653462/is-storing-a-delimited-list-in-a-database-column-really-that-bad – Nick Sep 09 '20 at 08:19
  • @Nick: You're absolutely right. Unfortunately, I'm already stuck with this data, and the format is comma-separated. – Ifedi Okonkwo Sep 09 '20 at 08:24
  • @IfediOkonkwo so which version of MySQL are you using? And how many values can be in the list? – Nick Sep 09 '20 at 08:25
  • @Nick, MySQL version 5.7 and 8.0; BTW, I believe the dynamic SQL limitation in triggers has always been there. The list can theoretically have up to 50 values, though in practice, 99% would be less than 20. – Ifedi Okonkwo Sep 09 '20 at 08:26
  • With 8.0 you could use `JSON_TABLE` to split the comma separated list into rows which you could use as a CTE for the `INSERT` query. – Nick Sep 09 '20 at 08:29
  • @Akina, please note I'm not referring to CSV list, but a table column containing numbers separated by commas. Please check the question code for an example. – Ifedi Okonkwo Sep 09 '20 at 08:29
  • @Nick, we have most of our production sites on 5.7, and few on 8. That being said, thanks for that interesting suggestion. The CTE concept is absolutely new to me, and I'll be studying it a bit more. – Ifedi Okonkwo Sep 09 '20 at 08:41
  • *please note I'm not referring to CSV list,* ??? I see *`-- This is a comma separated list of integers like "34,1,200,99"`*... maybe it is a time to post the task which you try to solve by your trigger? it is possible that you select incorrect way for to solve it, and it may be solved without dynamic SQL... *MySQL version 5.7 and 8.0; BTW, I believe the dynamic SQL limitation in triggers has always been there.* Imagine that somebody provides solution which needs the newest version - will you be glad if your version is too ancient for to apply this solution? – Akina Sep 09 '20 at 08:56
  • @Akina, I apologize for my ignorance, but when I hear "CSV" I think of a file and not just any string list. Here at SO, this is what the CSV tag info page has to say: https://stackoverflow.com/tags/csv/info. As for examples, I thought I had provided ample information about both the string list to be iterated through, and the query (`INSERT IGNORE INTO new_table ...`) which must be run on each element. – Ifedi Okonkwo Sep 09 '20 at 11:13
  • CSV means "Comma Separated Values". Can you find the word "file" in it? I cannot... – Akina Sep 09 '20 at 11:15

0 Answers0