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?SELECT
instrukcji w procedurach przechowywanych (DECLARE aCursor CURSOR FOR SELECT ...
)? Np.DECLARE theCursor CURSOR FOR CALL aProcedure()
?W większości DBMS tabele tymczasowe zachowują się do końca bieżącego połączenia, chyba że określono inaczej lub chyba że istnieje jawne wycofanie transakcji (w niektórych systemach wycofanie może wpłynąć tylko na zawartość tabeli, pozostawiając sam obiekt do ponownego wypełnienia w razie potrzeby) . Tabela nie będzie (domyślnie) widoczna dla innych połączeń bez względu na to, jak długo trwa połączenie, które ją tworzy.
Szybkie skanowanie w Google wydaje się wskazywać, że tak działa mySQL.
( http://www.tutorialspoint.com/mysql/mysql-temporary-tables.htm stwierdza „domyślnie wszystkie tabele tymczasowe są usuwane przez MySQL po zakończeniu połączenia z bazą danych”)
Istnieją jednak często sposoby zmiany tych zachowań. Na przykład w MS SQL Server możesz utworzyć tabelę tymczasową, która będzie widoczna dla wszystkich połączeń zamiast tylko bieżącej, nadając jej nazwę rozpoczynającą się od ##.
Zawsze upuszczam tabele tymczasowe, gdy tylko nie są już potrzebne, aby uniknąć możliwego zamieszania. Zostałem ugryziony wcześniej, gdy pula połączeń spowodowała utworzenie tabeli tymczasowej, powodując błędy, ponieważ tabela tymczasowa o tej samej nazwie została utworzona, ale nie została zniszczona w poprzedniej akcji, która korzystała z bieżącego połączenia.
źródło
DROP
przed odtworzeniem w IF początkowej warstwy. Dzięki za wkład!/ * podane zapytanie daje wynik pomyślnie ... po umieszczeniu tego zapytania w USP, a następnie wyświetleniu błędu plz help me..proc podano poniżej * /
CALL usp_GetEngMonthlyChart_Test („2014-01-01”, „2015-07-30”)
źródło