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.