Korzystam z rekurencyjnej procedury składowanej w MySQL do generowania tabeli tymczasowej o nazwie id_list
, ale muszę użyć wyników tej procedury w kolejnym zapytaniu dotyczącym wyboru, więc nie mogę DROP
tabeli tymczasowej w ramach procedury ...
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;
Podczas wywoływania procedury pierwsza wartość jest najwyższym identyfikatorem gałęzi, którą chcę, a druga to ta, tier
której używa procedura podczas rekurencji. Przed pętlą rekurencyjną sprawdza, czy tier = 0
i czy działa:
DROP TEMPORARY TABLE IF EXISTS id_list;
CREATE TEMPORARY TABLE IF NOT EXISTS id_list (iid CHAR(32) NOT NULL) ENGINE=memory;
Więc moje pytanie brzmi: jeśli nie DROP
tymczasowy MEMORY
stół pod koniec procedury lub w ramach mojej transakcji, jak długo ten stół będzie trwał w pamięci? Czy jest automatycznie usuwany po zakończeniu sesji, czy pozostanie w pamięci, dopóki połączenie będzie otwarte?
** NB Oczywistą odpowiedzią może być upuszczenie tabeli tymczasowej przed instrukcją zatwierdzenia, ale załóżmy przez chwilę, że nie mogę tego zrobić. *
EDYCJA : Aby być nieco bardziej precyzyjnym, co się stanie, jeśli zastosowane zostaną trwałe połączenia, czy tabela będzie utrzymywana przez wiele żądań? Jak dotąd wydaje się, że tak będzie i musielibyśmy wyraźnie usunąć tabelę tymczasową, aby zwolnić ten zasób.
AKTUALIZACJA : W oparciu o porady komentujących znalazłem sposób na dostosowanie mojej procedury składowanej, aby móc korzystać z tabeli TEMP MEMORY, ale móc ją jawnie DROP
na końcu ...
Zamiast wywoływać procedurę przechowywaną i korzystać z pozostałej tabeli TEMP w celu zebrania wyników w rzeczywistym zapytaniu, zmieniłem CALL
format, aby użyć trzeciej OUT
zmiennej, takiej jak:
CALL fetch_inheritance_groups('abc123','0',@IDS);
... następnie w ramach procedury składowanej dodałem drugi IF tier = 0
na samym końcu z następującymi informacjami:
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;
Tak więc wynikiem procedury składowanej jest teraz rozdzielona przecinkami lista identyfikatorów, z którymi jest zgodny FIND_IN_SET
, a więc końcowe zapytanie zostało zmodyfikowane, tak aby:
WHERE r.Group_ID = 'abc123' OR r.Group_ID IN (SELECT * FROM id_list)
... jest teraz ...
WHERE r.Group_ID = 'abc123' OR FIND_IN_SET(r.Group_ID,@IDS)
Voila! Dzięki komentatorom za Twój wkład i za podanie mi powodu musiałem spróbować trochę mocniej :)
DROP
tymczasowego PAMIĘCI stół. Czy zakładam poprawnie?