Я использую рекурсивную хранимую процедуру в 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
временное ПАМЯТЬ стол. Я правильно предполагаю?SELECT
оператора в хранимых процедурах (DECLARE aCursor CURSOR FOR SELECT ...
)? НапримерDECLARE theCursor CURSOR FOR CALL aProcedure()
?В большинстве СУБД временные таблицы сохраняются до конца текущего соединения, если не указано иное, или если нет явного отката транзакции (в некоторых системах откат может повлиять только на содержимое таблицы, оставляя сам объект при необходимости повторным заполнением) , Таблица не будет (по умолчанию) видимой для других соединений, независимо от того, как долго длится соединение, которое ее создает.
Быстрое сканирование в Google, похоже, показывает, как работает MySQL.
( http://www.tutorialspoint.com/mysql/mysql-teilitary-tables.htm заявляет, что «по умолчанию все временные таблицы удаляются MySQL, когда соединение с базой данных прекращается по умолчанию, все временные таблицы удаляются MySQL, когда соединение с вашей базой данных прекращается ")
Однако часто есть способы изменить это поведение. Например, в MS SQL Server вы можете создать временную таблицу, которая будет видна всем соединениям, а не только текущую, присвоив ей имя, начинающееся с ##.
Я всегда удаляю временные таблицы, как только они больше не нужны, чтобы избежать путаницы. Я был укушен раньше, когда пул соединений приводил к созданию временной таблицы, что приводило к ошибкам, поскольку временная таблица с тем же именем была создана, но не уничтожена в предыдущем действии, которое использовало текущее соединение.
источник
DROP
предварительное воссоздание в IF начального уровня. Спасибо за ваш вклад!/ * данный запрос дает результат успешно ... если поместить этот запрос в USP, а затем отобразится сообщение об ошибке, помогите мне .. процедура приведена ниже * /
CALL usp_GetEngMonthlyChart_Test ('2014-01-01', '2015-07-30')
источник