Ich benutze eine rekursive gespeicherte Prozedur in MySQL, um eine temporäre Tabelle mit dem Namen zu generieren id_list
, aber ich muss die Ergebnisse dieser Prozedur in einer nachfolgenden Auswahlabfrage verwenden, damit ich DROP
die temporäre Tabelle in der Prozedur nicht verwenden kann ...
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;
Beim Aufrufen der Prozedur ist der erste Wert die oberste ID des gewünschten Zweigs und der zweite Wert die, tier
die die Prozedur bei Rekursionen verwendet. Vor der rekursiven Schleife wird geprüft, ob tier = 0
und ob sie ausgeführt wird:
DROP TEMPORARY TABLE IF EXISTS id_list;
CREATE TEMPORARY TABLE IF NOT EXISTS id_list (iid CHAR(32) NOT NULL) ENGINE=memory;
Meine Frage lautet also: Wenn ich DROP
die temporäre MEMORY
Tabelle am Ende des Vorgangs oder innerhalb meiner Transaktion nicht erhalte, wie lange bleibt diese Tabelle im Speicher? Wird es nach Beendigung der Sitzung automatisch gelöscht oder verbleibt es im Speicher, solange die Verbindung geöffnet ist?
** NB Die naheliegende Antwort könnte darin bestehen, die temporäre Tabelle vor der Festschreibungsanweisung zu löschen, aber nehmen wir für einen Moment an, dass ich das nicht kann. *
EDIT : Genauer gesagt, was passiert, wenn dauerhafte Verbindungen verwendet werden, bleibt die Tabelle bei mehreren Anforderungen bestehen? Bisher scheint es so zu sein und wir müssten die temporäre Tabelle explizit entfernen, um diese Ressource freizugeben.
UPDATE : Basierend auf den Ratschlägen der Kommentatoren habe ich eine Möglichkeit gefunden, meine gespeicherte Prozedur so anzupassen, dass ich die TEMP MEMORY-Tabelle verwenden kann, sie aber DROP
am Ende explizit verwenden kann ...
Anstatt nur die gespeicherte Prozedur aufzurufen und die verbleibende TEMP-Tabelle zu verwenden, um die Ergebnisse in der tatsächlichen Abfrage zu erfassen, habe ich das CALL
Format geändert , um eine dritte OUT
Variable wie die folgende zu verwenden :
CALL fetch_inheritance_groups('abc123','0',@IDS);
... dann habe ich innerhalb der gespeicherten Prozedur IF tier = 0
ganz am Ende eine Sekunde mit folgendem hinzugefügt :
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;
Das Ergebnis der gespeicherten Prozedur ist nun eine durch Kommas getrennte Liste von IDs, mit denen kompatibel FIND_IN_SET
ist. Die endgültige Abfrage wurde folgendermaßen geändert:
WHERE r.Group_ID = 'abc123' OR r.Group_ID IN (SELECT * FROM id_list)
... ist jetzt ...
WHERE r.Group_ID = 'abc123' OR FIND_IN_SET(r.Group_ID,@IDS)
Voila! Vielen Dank an die Kommentatoren für deinen Beitrag und dafür, dass du mir den Grund gegeben hast, warum ich mich ein bisschen mehr anstrengen musste :)
DROP
den temporären MEMORY explizit benötigen Tabelle. Gehe ich richtig aus