Elimine todas as tabelas cujos nomes começam com uma determinada sequência


150

Como posso eliminar todas as tabelas cujos nomes começam com uma determinada sequência?

Eu acho que isso pode ser feito com algumas SQL dinâmicas e as INFORMATION_SCHEMAtabelas.

Respostas:


151

Pode ser necessário modificar a consulta para incluir o proprietário, se houver mais de uma no banco de dados.

DECLARE @cmd varchar(4000)
DECLARE cmds CURSOR FOR
SELECT 'drop table [' + Table_Name + ']'
FROM INFORMATION_SCHEMA.TABLES
WHERE Table_Name LIKE 'prefix%'

OPEN cmds
WHILE 1 = 1
BEGIN
    FETCH cmds INTO @cmd
    IF @@fetch_status != 0 BREAK
    EXEC(@cmd)
END
CLOSE cmds;
DEALLOCATE cmds

Isso é mais limpo do que usar uma abordagem em duas etapas para gerar script e executar. Mas uma vantagem da geração de scripts é que ela oferece a chance de revisar a totalidade do que será executado antes de realmente ser executado.

Eu sei que se eu fosse fazer isso em um banco de dados de produção, seria o mais cuidadoso possível.

Exemplo de edição de código corrigido.


5
Pode ser necessário executar esse script várias vezes devido a restrições de chave estrangeira entre as tabelas mestre e de detalhes.
Alexander Prokofyev

7
No SQL Server 2005, tive que alterar as duas últimas linhas para close cmds; deallocate cmds.
Hamish Grubijan

Aviso : Esta solução também pode excluir tabelas criadas pelo SQL Server! Minha solução abaixo evita isso e exclui tabelas em ordem de dependência de chave estrangeira.
Tony O'Hagan

Isto não funcionou para mim. A resposta a esta pergunta funcionou: stackoverflow.com/questions/5116296/…
Ayushmati

115
SELECT 'DROP TABLE "' + TABLE_NAME + '"' 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE '[prefix]%'

Isso irá gerar um script.

Adicionando cláusula para verificar a existência da tabela antes de excluir:

SELECT 'IF OBJECT_ID(''' +TABLE_NAME + ''') IS NOT NULL BEGIN DROP TABLE [' + TABLE_NAME + '] END;' 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE '[prefix]%'

10
Posso adicionar para remover os colchetes ao substituir "prefixo" pelo seu prefixo de destino.
Levitikon

10
MYSQL: SELECT concat ('DROP TABLE', TABLE_NAME, ";") como dados FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME COMO '[prefixo]%' --- para aqueles que como eu encontraram este tópico
Andre

1
O resultado também contém visualizações
Ondra

1
Não se esqueça de escapar _ se isso faz parte do seu prefixo, por exemplo. WHERE TABLE_NAME LIKE 'em\_%' ESCAPE '\';
EM0 29/09/2015

3
Isso gera um script, mas como se executa o script?
daOnlyBG 4/17/17

16

Isso fornecerá as tabelas em ordem de chave estrangeira e evitará a exclusão de algumas das tabelas criadas pelo SQL Server. O t.Ordinalvalor dividirá as tabelas em camadas de dependência.

WITH TablesCTE(SchemaName, TableName, TableID, Ordinal) AS
(
    SELECT OBJECT_SCHEMA_NAME(so.object_id) AS SchemaName,
        OBJECT_NAME(so.object_id) AS TableName,
        so.object_id AS TableID,
        0 AS Ordinal
    FROM sys.objects AS so
    WHERE so.type = 'U'
        AND so.is_ms_Shipped = 0
        AND OBJECT_NAME(so.object_id)
        LIKE 'MyPrefix%'

    UNION ALL
    SELECT OBJECT_SCHEMA_NAME(so.object_id) AS SchemaName,
        OBJECT_NAME(so.object_id) AS TableName,
        so.object_id AS TableID,
        tt.Ordinal + 1 AS Ordinal
    FROM sys.objects AS so
        INNER JOIN sys.foreign_keys AS f
            ON f.parent_object_id = so.object_id
                AND f.parent_object_id != f.referenced_object_id
        INNER JOIN TablesCTE AS tt
            ON f.referenced_object_id = tt.TableID
    WHERE so.type = 'U'
        AND so.is_ms_Shipped = 0
        AND OBJECT_NAME(so.object_id)
        LIKE 'MyPrefix%'
)
SELECT DISTINCT t.Ordinal, t.SchemaName, t.TableName, t.TableID
FROM TablesCTE AS t
    INNER JOIN
    (
        SELECT
            itt.SchemaName AS SchemaName,
            itt.TableName AS TableName,
            itt.TableID AS TableID,
            Max(itt.Ordinal) AS Ordinal
        FROM TablesCTE AS itt
        GROUP BY itt.SchemaName, itt.TableName, itt.TableID
    ) AS tt
        ON t.TableID = tt.TableID
            AND t.Ordinal = tt.Ordinal
ORDER BY t.Ordinal DESC, t.TableName ASC


3
Solução rápida: TableName aparece algumas vezes nas cláusulas WHERE e deve ser substituído por OBJECT_NAME (so.object_id). Bom roteiro!
Witttness

6

No Oracle XE, isso funciona:

SELECT 'DROP TABLE "' || TABLE_NAME || '";'
FROM USER_TABLES
WHERE TABLE_NAME LIKE 'YOURTABLEPREFIX%'

Ou se você deseja remover as restrições e liberar espaço também, use o seguinte:

SELECT 'DROP TABLE "' || TABLE_NAME || '" cascade constraints PURGE;'
FROM USER_TABLES
WHERE TABLE_NAME LIKE 'YOURTABLEPREFIX%'

O que gerará várias DROP TABLE cascade constraints PURGEinstruções ...

Para VIEWSusar isto:

SELECT 'DROP VIEW "' || VIEW_NAME || '";'
FROM USER_VIEWS
WHERE VIEW_NAME LIKE 'YOURVIEWPREFIX%'

Funcionou perfeitamente. Tinha 61.037 tabelas vazias para excluir de um banco de dados usado para o controle de qualidade. Eu usei o exemplo de restrições em cascata. Gerou a saída, copiou tudo em um script e o executou. Levou uma eternidade, mas funcionou como um encanto! Obrigado!
Tehbeardedone 30/10/19

5

Vi este post quando estava procurando pela instrução mysql para soltar todas as tabelas do WordPress com base no @Xenph Yan. Aqui está o que eu fiz eventualmente:

SELECT CONCAT(  'DROP TABLE `', TABLE_NAME,  '`;' ) AS query
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE  'wp_%'

isso fornecerá o conjunto de consultas suspensas para todas as tabelas que começa com wp_


5

Aqui está a minha solução:

SELECT CONCAT('DROP TABLE `', TABLE_NAME,'`;') 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE 'TABLE_PREFIX_GOES_HERE%';

E é claro que você precisa substituir TABLE_PREFIX_GOES_HEREpelo seu prefixo.


5
EXEC sp_MSforeachtable 'if PARSENAME("?",1) like ''%CertainString%'' DROP TABLE ?'

Editar:

sp_MSforeachtable não está documentado, portanto, não é adequado para produção, pois seu comportamento pode variar dependendo da versão do MS_SQL.


Uma linha impressionante! Isso deve ser votado para o topo.
user3413723

4
CREATE PROCEDURE usp_GenerateDROP
    @Pattern AS varchar(255)
    ,@PrintQuery AS bit
    ,@ExecQuery AS bit
AS
BEGIN
    DECLARE @sql AS varchar(max)

    SELECT @sql = COALESCE(@sql, '') + 'DROP TABLE [' + TABLE_NAME + ']' + CHAR(13) + CHAR(10)
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_NAME LIKE @Pattern

    IF @PrintQuery = 1 PRINT @sql
    IF @ExecQuery = 1 EXEC (@sql)
END

2

A resposta de Xenph Yan foi muito mais limpa que a minha, mas aqui é a minha.

DECLARE @startStr AS Varchar (20)
SET @startStr = 'tableName'

DECLARE @startStrLen AS int
SELECT @startStrLen = LEN(@startStr)

SELECT 'DROP TABLE ' + name FROM sysobjects
WHERE type = 'U' AND LEFT(name, @startStrLen) = @startStr

Apenas mude tableNamepara os caracteres que você deseja pesquisar.


1

Isso funcionou para mim.

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += '
DROP TABLE ' 
    + QUOTENAME(s.name)
    + '.' + QUOTENAME(t.name) + ';'
    FROM sys.tables AS t
    INNER JOIN sys.schemas AS s
    ON t.[schema_id] = s.[schema_id] 
    WHERE t.name LIKE 'something%';

PRINT @sql;
-- EXEC sp_executesql @sql;

0
select 'DROP TABLE ' + name from sysobjects
where type = 'U' and sysobjects.name like '%test%'

- Teste é o nome da tabela


na verdade, isso não executa nada, basta retornar um monte de comandos.
Rabino Stealth

0
SELECT 'if object_id(''' + TABLE_NAME + ''') is not null begin drop table "' + TABLE_NAME + '" end;' 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE '[prefix]%'

0

Eu tive que fazer uma ligeira derivação na resposta de Xenph Yan, suspeito, porque tinha tabelas que não estavam no esquema padrão.

SELECT 'DROP TABLE Databasename.schema.' + TABLE_NAME 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE 'strmatch%'

0

No caso de tabelas temporárias, convém tentar

SELECT 'DROP TABLE "' + t.name + '"' 
FROM tempdb.sys.tables t
WHERE t.name LIKE '[prefix]%'
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.