Here is how I would write this routine if the table name and field name are really dynamic:
BEGIN
INSERT IGNORE INTO tag (cod, tag) values (cod_tag_in, tag_in);
SET @query = CONCAT('INSERT INTO `', table_in, '` (cod, `', table_field_in, '`, tag_cod) values (?, ?, ?)');
SET @cod = app_cod_in, @field = section_code_in, @tag_cod = cod_tag_in;
PREPARE stmt FROM @query;
EXECUTE stmt USING @cod, @field, @tag_cod;
DEALLOCATE PREPARE stmt;
END
Use query parameters so you don't have to use all those meticulous quotes for the values. This also protects you in case the values themselves contain quote characters.
I don't see the need for the subquery, since the value you just inserted in the the tag table should be the same as cod_tag_in anyway.
You do need the breaks in quotes for the dynamic table name and dynamic field name, because you can't use parameters as table or column identifiers.
I put back-ticks around the table and field name, just in case these identifiers require them (conflict with SQL reserved keywords, contain whitespace or punctuation, etc.).
However, you shouldn't even use dynamic SQL for this at all. You should use a CASE statement for the tables you need to support:
BEGIN
INSERT IGNORE INTO tag (cod, tag) values (cod_tag_in, tag_in);
CASE table_in
WHEN 'mytable1' THEN
INSERT INTO mytable1 (cod, myfield1, tag_cod) VALUES (app_cod_in, section_code_in, cod_tag_in);
WHEN 'mytable2' THEN
INSERT INTO mytable2 (cod, myfield2, tag_cod) VALUES (app_cod_in, section_code_in, cod_tag_in);
WHEN 'mytable3' THEN
INSERT INTO mytable3 (cod, myfield3, tag_cod) VALUES (app_cod_in, section_code_in, cod_tag_in);
ELSE
SIGNAL SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'Unknown table';
END CASE;
END
This means you don't have to worry about CONCAT()-ing any fragments of SQL, and you don't have to worry about SQL injection risks, and you don't have to worry about table or column identifiers that have conflicting characters.
But you are limited to the tables you have coded in the CASE statement. If you are in the habit of creating new tables on the fly frequently, you'd have to replace the stored procedure with longer and longer CASE statements. But if you need to do that, I'd reconsider the design that so frequently requires new tables of similar structure.