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?SELECT
declaración en procedimientos almacenados (DECLARE aCursor CURSOR FOR SELECT ...
)? P.ej.DECLARE theCursor CURSOR FOR CALL aProcedure()
?En la mayoría de los DBMS, las tablas temporales sobreviven hasta el final de la conexión actual, a menos que se especifique lo contrario o que exista una reversión de transacción explícita (en algunos sistemas, una reversión solo puede afectar el contenido de la tabla, dejando el objeto en sí mismo para ser repoblado si es necesario) . La tabla no (por defecto) será visible para otras conexiones, sin importar cuánto tiempo dure la conexión que la crea.
Un escaneo rápido en Google parece indicar que así es como opera mySQL.
( http://www.tutorialspoint.com/mysql/mysql-temporary-tables.htm establece "de forma predeterminada, MySQL elimina todas las tablas temporales cuando finaliza la conexión de la base de datos. De forma predeterminada, MySQL elimina todas las tablas temporales cuando su conexión de base de datos se termina ")
Sin embargo, a menudo hay formas de alterar estos comportamientos. Por ejemplo, en MS SQL Server puede crear una tabla temporal que sea visible para todas las conexiones en lugar de solo la actual dándole un nombre que comience ##.
Siempre elimino las tablas temporales tan pronto como ya no son necesarias para evitar posibles confusiones. Me han mordido antes donde la agrupación de conexiones dio como resultado la creación de una tabla temporal que causa errores porque se creó una tabla temporal del mismo nombre pero no se destruyó en una acción anterior que utilizó la conexión actual.
fuente
DROP
antes de recrear dentro del IF del nivel inicial. ¡Gracias por tu contribución!/ * la consulta dada da un resultado exitoso ... cuando coloca esta consulta en USP y luego muestra un error, por favor ayúdame ... el proceso se proporciona a continuación * /
LLAME a usp_GetEngMonthlyChart_Test ('2014-01-01', '2015-07-30')
fuente