SQL: deletando tabelas com prefixo


Respostas:


178

Você não pode fazer isso com apenas um único comando MySQL, no entanto, você pode usar o MySQL para construir a instrução para você:

No shell do MySQL ou por meio do PHPMyAdmin, use a seguinte consulta

SELECT CONCAT( 'DROP TABLE ', GROUP_CONCAT(table_name) , ';' ) 
    AS statement FROM information_schema.tables 
    WHERE table_name LIKE 'myprefix_%';

Isso irá gerar uma instrução DROP que você pode copiar e executar para eliminar as tabelas.

EDIT: Um aviso aqui - a instrução gerada acima irá eliminar todas as tabelas em todos os bancos de dados com esse prefixo. Se você quiser limitá-lo a um banco de dados específico, modifique a consulta para ter a seguinte aparência e substitua database_name por seu próprio database_name:

SELECT CONCAT( 'DROP TABLE ', GROUP_CONCAT(table_name) , ';' ) 
    AS statement FROM information_schema.tables 
    WHERE table_schema = 'database_name' AND table_name LIKE 'myprefix_%';

Eu tenho apenas um banco de dados, então não precisarei do segundo.
Deniz Zoeteman

4
@ElijahLynn a fonte de limite é provavelmente devido ao comprimento máximo de GROUP_CONCAT. você pode aumentá-lo, veja por exemplo aqui
Asaf David

7
Nota para self.Increase num of max char: SET SESSION group_concat_max_len = 999999999;
Mohammed Joraid,

2
Observe que, em alguns casos, é necessário escapar sublinhados em nomes de prefixo de tabela[...] LIKE 'myprefix\_%';
Magictallguy

1
Isso retorna vários nomes_tabela duplicados. A resposta que Pankaj Khurana postou funciona melhor IMHO.
Jeremy

37

Algumas das respostas anteriores foram muito boas. Reuni suas ideias com algumas noções de outras respostas na web.

Eu precisava excluir todas as tabelas começando com 'temp_' Depois de algumas iterações, eu vim com este bloco de código:

-- Set up variable to delete ALL tables starting with 'temp_'
SET GROUP_CONCAT_MAX_LEN=10000;
SET @tbls = (SELECT GROUP_CONCAT(TABLE_NAME)
               FROM information_schema.TABLES
              WHERE TABLE_SCHEMA = 'my_database'
                AND TABLE_NAME LIKE 'temp_%');
SET @delStmt = CONCAT('DROP TABLE ',  @tbls);
-- SELECT @delStmt;
PREPARE stmt FROM @delStmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Espero que isso seja útil para outros programadores de MySQL / PHP.


1
Esta é exatamente a resposta certa. Outras respostas usam várias etapas ou exigem que seja feito manualmente. Não sei como esta resposta não tem mais votos após 4 anos!
gbe

25
show tables like 'prefix_%';

copie os resultados e cole-os em um editor de texto ou envie a consulta para um arquivo, use algumas pesquisas e substituições para remover a formatação indesejada e substituir \n por uma vírgula, coloque um ;no final e adicione a tabela suspensa à frente.

você obterá algo parecido com isto:

drop table myprefix_1, myprefix_2, myprefix_3;

1
não tive acesso a information_schema.tables no webhost que estou usando, então esse foi o caminho a seguir, obrigado!
Florent Roques

10

A solução @andre-miller é boa, mas há ainda melhor e um pouco mais profissional que o ajudará a executar tudo de uma vez. Ainda precisará de mais de um comando, mas esta solução permitirá que você use o SQL para compilações automatizadas.

SET @tbls = (SELECT GROUP_CONCAT(TABLE_NAME) 
    FROM information_schema.TABLES
    WHERE TABLE_NAME LIKE 'myprefix_%');
PREPARE stmt FROM 'DROP TABLE @tbls';
EXECUTE stmt USING @tbls;
DEALLOCATE PREPARE stmt;

Nota: este código depende da plataforma, é para MySQL mas com certeza pode ser implementado para Postgre, Oracle e MS SQL com pequenas alterações.


ERROR 1064 (42000): você tem um erro na sintaxe SQL; verifique o manual que corresponde à versão do seu servidor MySQL para obter a sintaxe correta para usar próximo a '@tbls' na linha 1 ERROR 1243 (HY000): Manipulador de instrução preparado desconhecido (stmt) fornecido para EXECUTE ERROR 1243 (HY000): Manipulador de instrução preparado desconhecido (stmt) dado a DEALLOCATE PREPARE
Roni Tovi

Erro de sintaxe em: PREPARE stmt FROM 'DROP TABLE @tbls';
ledawg de

5
SELECT CONCAT("DROP TABLE ", table_name, ";") 
FROM information_schema.tables
WHERE table_schema = "DATABASE_NAME" 
AND table_name LIKE "PREFIX_TABLE_NAME%";

3

Eu descarto a tabela com sucesso ao editar a consulta para gostar disso

SET GROUP_CONCAT_MAX_LEN=10000;
SET FOREIGN_KEY_CHECKS = 0;
SET @tbls = (SELECT GROUP_CONCAT(CONCAT('`', TABLE_NAME, '`'))
           FROM information_schema.TABLES
          WHERE TABLE_SCHEMA = 'pandora'
            AND TABLE_NAME LIKE 'temp_%');
SET @delStmt = CONCAT('DROP TABLE ',  @tbls);
-- SELECT @delStmt;
PREPARE stmt FROM @delStmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET FOREIGN_KEY_CHECKS = 1;

Este foi o único que descobri que fez toda a operação de uma vez enquanto abordava as restrições de chave estrangeira.
Evan Mattson

2

Você pode fazer isso em um comando com MySQL:

drop table myprefix_1, myprefix_2, myprefix_3;

Você provavelmente terá que construir a lista de tabelas dinamicamente no código.

Uma abordagem alternativa seria usar a biblioteca de rotina de propósito geral para MySQL 5.


2

Eu só queria postar o SQL exato que usei - é uma espécie de mistura das 3 principais respostas:

SET GROUP_CONCAT_MAX_LEN=10000;

SET @del = (
    SELECT      CONCAT('DROP TABLE ', GROUP_CONCAT(TABLE_NAME), ';')
    FROM        information_schema.TABLES

    WHERE       TABLE_SCHEMA = 'database_name'
    AND         TABLE_NAME LIKE 'prefix_%'
);

PREPARE stmt FROM @del;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

2

Apenas outra solução usando GROUP_CONCAT para executar uma consulta drop como
DROP TABLE table1, table2, ..

SET @Drop_Stm = CONCAT('DROP TABLE ', (
      SELECT GROUP_CONCAT(TABLE_NAME) AS All_Tables FROM information_schema.tables 
      WHERE TABLE_NAME LIKE 'prefix_%' AND TABLE_SCHEMA = 'database_name'
)); 
PREPARE Stm FROM @Drop_Stm; 
EXECUTE Stm;
DEALLOCATE PREPARE Stm;

1

Descobri que as instruções preparadas eram um pouco complicadas de fazer funcionar para mim, mas definir o GROUP_CONCAT_MAX_LENfoi essencial quando você tem muitas tabelas. Isso resultou em um processo simples de três etapas com recortar e colar da linha de comando do mysql que funcionou muito bem para mim:

SET GROUP_CONCAT_MAX_LEN=10000;
SELECT CONCAT( 'DROP TABLE ', GROUP_CONCAT(table_name) , ';' ) 
    AS statement FROM information_schema.tables 
    WHERE table_name LIKE 'myprefix_%';

Em seguida, recorte e cole cuidadosamente a declaração DROP longa resultante .


terminar a consulta com em \Gvez de ;fornece uma saída um pouco mais limpa
Stuart Cardall
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.