Estoy usando un procedimiento almacenado recursivo en MySQL para generar una tabla temporal llamada id_list
, pero debo usar los resultados de ese procedimiento en una consulta de selección de seguimiento, por lo que no puedo DROP
la tabla temporal dentro del procedimiento ...
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;
Al llamar al procedimiento, el primer valor es la ID superior de la rama que quiero, y el segundo es el tier
que utiliza el procedimiento durante las recursiones. Antes del bucle recursivo, comprueba si tier = 0
se ejecuta y si es así:
DROP TEMPORARY TABLE IF EXISTS id_list;
CREATE TEMPORARY TABLE IF NOT EXISTS id_list (iid CHAR(32) NOT NULL) ENGINE=memory;
Entonces mi pregunta es: si no hago DROP
la MEMORY
tabla temporal al final del procedimiento, o dentro de mi transacción, ¿cuánto tiempo durará esa tabla en la memoria? ¿Se descarta automáticamente una vez que finaliza la sesión, o permanecerá en la memoria mientras la conexión esté abierta?
** Nota: la respuesta obvia podría ser abandonar la tabla temporal antes de la declaración de confirmación, pero supongamos por un momento que no puedo hacer eso. *
EDITAR : Para ser un poco más precisos, ¿qué pasa si se emplean conexiones persistentes, la tabla persistirá a través de múltiples solicitudes? Hasta ahora parece que lo hará y que tendríamos que eliminar explícitamente la tabla temporal para liberar ese recurso.
ACTUALIZACIÓN : Basado en el consejo de los comentaristas, he encontrado una forma de ajustar mi procedimiento almacenado para que pueda utilizar la tabla TEMP MEMORY, pero poder explícitamente DROP
al final ...
En lugar de simplemente llamar al procedimiento almacenado y usar la tabla TEMP restante para recopilar los resultados en la consulta real, he cambiado el CALL
formato para usar una tercera OUT
variable de esta manera:
CALL fetch_inheritance_groups('abc123','0',@IDS);
... luego, dentro del procedimiento almacenado, agregué un segundo IF tier = 0
al final con lo siguiente:
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;
Por lo tanto, el resultado del procedimiento almacenado ahora es una lista separada por comas de ID que es compatible y FIND_IN_SET
, por lo tanto, la consulta final se modificó para que:
WHERE r.Group_ID = 'abc123' OR r.Group_ID IN (SELECT * FROM id_list)
... es ahora ...
WHERE r.Group_ID = 'abc123' OR FIND_IN_SET(r.Group_ID,@IDS)
Voila! Gracias a los comentaristas por su aporte y por darme la razón por la que necesitaba esforzarme un poco más :)
DROP
la MEMORIA temporal mesa. ¿Asumo correctamente?