Estou usando um procedimento armazenado recursivo no MySQL para gerar uma tabela temporária chamada id_list
, mas devo usar os resultados desse procedimento em uma consulta de seleção de acompanhamento, para que não possa DROP
a tabela temporária dentro do procedimento ...
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;
Ao chamar o procedimento, o primeiro valor é o ID superior da ramificação que desejo e o segundo é o tier
que o procedimento usa durante as recursões. Antes do loop recursivo, ele verifica se tier = 0
e se é executado:
DROP TEMPORARY TABLE IF EXISTS id_list;
CREATE TEMPORARY TABLE IF NOT EXISTS id_list (iid CHAR(32) NOT NULL) ENGINE=memory;
Portanto, minha pergunta é: se eu não fizer DROP
a MEMORY
tabela temporária no final do procedimento ou dentro da minha transação, por quanto tempo essa tabela persistirá na memória? Ele é descartado automaticamente quando a sessão termina ou permanecerá na memória enquanto a conexão estiver aberta?
** NB A resposta óbvia pode ser descartar a tabela temporária antes da declaração de commit, mas vamos assumir por um momento que eu não posso fazer isso. *
EDIT : Para ser um pouco mais preciso, e se conexões persistentes forem empregadas, a tabela persistirá por meio de várias solicitações? Até agora, parece que sim e que precisaríamos remover explicitamente a tabela temporária para liberar esse recurso.
ATUALIZAÇÃO : Com base nos conselhos dos comentaristas, encontrei uma maneira de ajustar meu procedimento armazenado para poder utilizar a tabela TEMP MEMORY, mas poder explicitamente explicá- DROP
la no final ...
Em vez de apenas chamar o procedimento armazenado e usar a tabela TEMP restante para reunir os resultados na consulta real, alterei o CALL
formato para usar uma terceira OUT
variável da seguinte forma:
CALL fetch_inheritance_groups('abc123','0',@IDS);
... então, dentro do procedimento armazenado, adicionei um segundo IF tier = 0
no final com o seguinte:
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;
Portanto, o resultado do procedimento armazenado agora é uma lista separada por vírgula de IDs compatíveis e FIND_IN_SET
, portanto, a consulta final foi modificada para que:
WHERE r.Group_ID = 'abc123' OR r.Group_ID IN (SELECT * FROM id_list)
... é agora ...
WHERE r.Group_ID = 'abc123' OR FIND_IN_SET(r.Group_ID,@IDS)
Voila! Agradeço aos comentaristas por sua contribuição e por me darem o motivo de eu precisar me esforçar um pouco mais :)
DROP
a MEMÓRIA temporária mesa. Eu assumo corretamente?SELECT
instrução nos procedimentos armazenados (DECLARE aCursor CURSOR FOR SELECT ...
)? Por exemplo.DECLARE theCursor CURSOR FOR CALL aProcedure()
?Na maioria das tabelas temporárias de DBMSs, persiste até o final da conexão atual, a menos que seja especificado de outra forma ou a menos que haja uma reversão explícita de transação (em alguns sistemas, uma reversão pode afetar apenas o conteúdo da tabela, deixando o próprio objeto para ser repovoado, se necessário) . A tabela não será (por padrão) visível para outras conexões, independentemente da duração da conexão que a cria.
Uma rápida verificação no Google parece indicar que é assim que o mySQL opera.
( http://www.tutorialspoint.com/mysql/mysql-temporary-tables.htm declara "por padrão, todas as tabelas temporárias são excluídas pelo MySQL quando a conexão com o banco de dados é encerrada. Por padrão, todas as tabelas temporárias são excluídas pelo MySQL quando sua conexão com o banco de dados é encerrada ")
Muitas vezes existem maneiras de alterar esses comportamentos. Por exemplo, no MS SQL Server, você pode criar uma tabela temporária que é visível para todas as conexões, e não apenas a atual, atribuindo um nome a partir de ##.
Eu sempre largo tabelas temporárias assim que elas não são mais necessárias para evitar possíveis confusões. Fui mordido antes em que o pool de conexões resultou na criação temporária de tabelas, causando erros porque uma tabela temporária com o mesmo nome havia sido criada, mas não destruída em uma ação anterior que usava a conexão atual.
fonte
DROP
antes da recriação no FI da camada inicial. Obrigado pela sua contribuição!/ * determinada consulta fornece resultado com sucesso ... quando coloca esta consulta na USP e mostra o erro plz help me..proc é dado abaixo * /
CALL usp_GetEngMonthlyChart_Test ('2014-01-01', '2015-07-30')
fonte