I'm using a recursive stored procedure in MySQL to generate a temporary table called id_list
, but I must use the results of that procedure in a follow up select query, so I can't DROP
the temporary table within the procedure...
BEGIN;
/* generates the temporary table of ID's */
CALL fetch_inheritance_groups('abc123',0);
/* uses the results of the stored procedure in the WHERE */
SELECT a.User_ID
FROM usr_relationships r
INNER JOIN usr_accts a ON a.User_ID = r.User_ID
WHERE r.Group_ID = 'abc123' OR r.Group_ID IN (SELECT * FROM id_list)
GROUP BY r.User_ID;
COMMIT;
When calling the procedure, the first value is the top ID of the branch I want, and the second is the tier
which the procedure uses during recursions. Prior to the recursive loop it checks if tier = 0
and if it is it runs:
DROP TEMPORARY TABLE IF EXISTS id_list;
CREATE TEMPORARY TABLE IF NOT EXISTS id_list (iid CHAR(32) NOT NULL) ENGINE=memory;
So my question is: If I don't DROP
the temporary MEMORY
table at the end of the procedure, or within my transaction, how long will that table persist in memory? Is it automatically dropped once the session ends, or will it remain in memory as long as the connection is open?
**N.B. The obvious answer might be to drop the temp table prior to the commit statement, but lets assume for a moment that I can't do that.*
EDIT: To be a little more precise, what if persistent connections are employed, will the table persist through multiple requests? So far it seems that it will and that we would need to explicitly remove the temp table to free up that resource.
UPDATE: Based on the advice from the commenters, I've found a way of adjusting my stored procedure so that I can utilize the TEMP MEMORY table, but be able to explicitly DROP
it at the end...
Rather than just calling the stored procedure and using the remaining TEMP table to gather the results in the actual query, I've changed the CALL
format to use a third OUT
variable like so:
CALL fetch_inheritance_groups('abc123','0',@IDS);
... then within the stored procedure, I added a second IF tier = 0
at the very end with the following:
IF tier = 0
THEN
SELECT GROUP_CONCAT(DISTINCT iid SEPARATOR ',') FROM id_list INTO inherited_set;
DROP TEMPORARY TABLE IF EXISTS id_list;
END IF;
So the result of the stored procedure is now a comma separated list of ID's that is compatible with FIND_IN_SET
, and so the final query was modified so that:
WHERE r.Group_ID = 'abc123' OR r.Group_ID IN (SELECT * FROM id_list)
... is now ...
WHERE r.Group_ID = 'abc123' OR FIND_IN_SET(r.Group_ID,@IDS)
Voila! Thanks to the commentors for your input, and for giving me the reason I needed to try a little harder :)