J'utilise une procédure stockée récursive dans MySQL pour générer une table temporaire appelée id_list
, mais je dois utiliser les résultats de cette procédure dans une requête de sélection de suivi, donc je ne peux pas DROP
la table temporaire dans la procédure ...
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;
Lors de l'appel de la procédure, la première valeur est l'ID supérieur de la branche que je veux, et la seconde est celle tier
que la procédure utilise lors des récursions. Avant la boucle récursive, il vérifie si tier = 0
et si elle est exécutée:
DROP TEMPORARY TABLE IF EXISTS id_list;
CREATE TEMPORARY TABLE IF NOT EXISTS id_list (iid CHAR(32) NOT NULL) ENGINE=memory;
Ma question est donc la suivante: si je n'utilise pas DROP
la MEMORY
table temporaire à la fin de la procédure ou dans ma transaction, combien de temps cette table persistera-t-elle en mémoire? Est-il automatiquement supprimé une fois la session terminée ou restera-t-il en mémoire tant que la connexion sera ouverte?
** NB La réponse évidente pourrait être de supprimer la table temporaire avant l'instruction commit, mais supposons un instant que je ne peux pas faire ça. *
EDIT : Pour être un peu plus précis, que se passe-t-il si des connexions persistantes sont utilisées, la table persistera-t-elle à travers plusieurs requêtes? Jusqu'à présent, il semble que ce sera le cas et que nous devions supprimer explicitement la table temporaire pour libérer cette ressource.
MISE À JOUR : Sur la base des conseils des commentateurs, j'ai trouvé un moyen d'ajuster ma procédure stockée afin que je puisse utiliser la table TEMP MEMORY, mais pouvoir l'expliciter DROP
à la fin ...
Plutôt que d'appeler simplement la procédure stockée et d'utiliser la table TEMP restante pour rassembler les résultats dans la requête réelle, j'ai changé le CALL
format pour utiliser une troisième OUT
variable comme ceci:
CALL fetch_inheritance_groups('abc123','0',@IDS);
... puis dans la procédure stockée, j'ai ajouté une seconde IF tier = 0
à la fin avec ce qui suit:
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;
Ainsi, le résultat de la procédure stockée est maintenant une liste d'ID séparés par des virgules qui est compatible avec FIND_IN_SET
, et donc la requête finale a été modifiée de sorte que:
WHERE r.Group_ID = 'abc123' OR r.Group_ID IN (SELECT * FROM id_list)
... est maintenant ...
WHERE r.Group_ID = 'abc123' OR FIND_IN_SET(r.Group_ID,@IDS)
Voila! Merci aux commentateurs pour votre contribution et pour m'avoir donné la raison pour laquelle je devais essayer un peu plus fort :)
DROP
la MEMORY temporaire table. Dois-je supposer correctement?