Я использую рекурсивную хранимую процедуру в MySQL для создания временной таблицы с именем id_list
, но я должен использовать результаты этой процедуры в последующем запросе выбора, поэтому я не могу DROP
использовать временную таблицу в процедуре ...
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;
При вызове процедуры первое значение - это верхний идентификатор нужной мне ветви, а второе - это то, tier
которое процедура использует во время рекурсии. Перед рекурсивным циклом он проверяет, tier = 0
выполняется ли он:
DROP TEMPORARY TABLE IF EXISTS id_list;
CREATE TEMPORARY TABLE IF NOT EXISTS id_list (iid CHAR(32) NOT NULL) ENGINE=memory;
Итак, мой вопрос: если у меня нет DROP
временной MEMORY
таблицы в конце процедуры или в моей транзакции, как долго эта таблица будет храниться в памяти? Будет ли он автоматически удален после завершения сеанса или останется в памяти до тех пор, пока соединение открыто?
** NB. Очевидный ответ может состоять в том, чтобы убрать временную таблицу перед оператором commit, но давайте на минутку предположим, что я не могу этого сделать. *
РЕДАКТИРОВАТЬ : Чтобы быть более точным, что, если постоянные соединения используются, таблица будет сохраняться через несколько запросов? До сих пор кажется, что так и будет, и что нам потребуется явно удалить временную таблицу, чтобы освободить этот ресурс.
ОБНОВЛЕНИЕ : Основываясь на рекомендациях комментаторов, я нашел способ настроить свою хранимую процедуру так, чтобы я мог использовать таблицу TEMP MEMORY, но иметь возможность явно DROP
ее в конце ...
Вместо того, чтобы просто вызывать хранимую процедуру и использовать оставшуюся таблицу TEMP для сбора результатов в реальном запросе, я изменил CALL
формат, чтобы использовать третью OUT
переменную, например, так:
CALL fetch_inheritance_groups('abc123','0',@IDS);
... затем в хранимой процедуре я добавил секунду IF tier = 0
в самом конце со следующим:
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;
Таким образом, результатом хранимой процедуры теперь является список идентификаторов, разделенных запятыми, которые совместимы FIND_IN_SET
, и поэтому окончательный запрос был изменен так, чтобы:
WHERE r.Group_ID = 'abc123' OR r.Group_ID IN (SELECT * FROM id_list)
... сейчас ...
WHERE r.Group_ID = 'abc123' OR FIND_IN_SET(r.Group_ID,@IDS)
Вуаля! Спасибо комментаторам за ваш вклад и за то, что я объяснил причину, по которой мне нужно было постараться немного усерднее :)
DROP
временное ПАМЯТЬ стол. Я правильно предполагаю?