Descarte todas las tablas cuyos nombres comiencen con una cadena determinada

150

¿Cómo puedo descartar todas las tablas cuyos nombres comienzan con una cadena dada?

Creo que esto se puede hacer con un poco de SQL dinámico y las INFORMATION_SCHEMAtablas.

Blorgbeard está fuera
fuente

Respuestas:

151

Es posible que deba modificar la consulta para incluir al propietario si hay más de uno en la base de datos.

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

Esto es más limpio que usar un enfoque de dos pasos para generar script más ejecutar. Pero una ventaja de la generación de script es que le da la oportunidad de revisar la totalidad de lo que se ejecutará antes de que se ejecute realmente.

Sé que si hiciera esto contra una base de datos de producción, sería lo más cuidadoso posible.

Editar código de muestra arreglado.

Curt Hagenlocher
fuente
55
Es posible que deba ejecutar este script varias veces debido a restricciones de clave externa entre las tablas maestra y de detalle.
Alexander Prokofyev
77
En SQL Server 2005 tuve que cambiar las dos últimas líneas a close cmds; deallocate cmds.
Hamish Grubijan
Advertencia : ¡Esta solución también puede eliminar tablas creadas por SQL Server! Mi solución a continuación evita esto y elimina tablas en orden de dependencia de clave externa.
Tony O'Hagan
Esto no funcionó para mí. La respuesta a esta pregunta funcionó: stackoverflow.com/questions/5116296/…
Ayushmati
115
SELECT 'DROP TABLE "' + TABLE_NAME + '"' 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE '[prefix]%'

Esto generará un script.

Agregar una cláusula para verificar la existencia de la tabla antes de eliminar:

SELECT 'IF OBJECT_ID(''' +TABLE_NAME + ''') IS NOT NULL BEGIN DROP TABLE [' + TABLE_NAME + '] END;' 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE '[prefix]%'
Xenph Yan
fuente
10
Podría agregar para eliminar los corchetes al reemplazar "prefijo" con su prefijo de destino.
Levitikon
10
MYSQL: SELECCIONE concat ('DROP TABLE', TABLE_NAME, ";") como datos DE INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE '[prefijo]%' --- para aquellos que como yo encontraron este hilo
Andre
1
El resultado también contiene puntos de vista
Ondra
1
No olvide escapar _ si eso es parte de su prefijo, por ejemplo. WHERE TABLE_NAME LIKE 'em\_%' ESCAPE '\';
EM0
3
Esto genera un script, pero ¿cómo se ejecuta el script?
daOnlyBG
16

Esto le dará las tablas en orden de clave externa y evitará que se caigan algunas de las tablas creadas por SQL Server. El t.Ordinalvalor dividirá las tablas en capas de dependencia.

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
Tony O'Hagan
fuente
3
Solución rápida: TableName aparece varias veces en las cláusulas WHERE y debe reemplazarse con OBJECT_NAME (so.object_id). Buen guión!
Witttness
6

En Oracle XE esto funciona:

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

O si desea eliminar las restricciones y liberar espacio también, use esto:

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

Lo que generará un montón de DROP TABLE cascade constraints PURGE declaraciones ...

Para VIEWSusar esto:

SELECT 'DROP VIEW "' || VIEW_NAME || '";'
FROM USER_VIEWS
WHERE VIEW_NAME LIKE 'YOURVIEWPREFIX%'
Rosdi Kasim
fuente
Funcionó perfectamente. Tenía 61.037 tablas vacías para eliminar de una base de datos utilizada para el control de calidad. Usé el ejemplo de restricciones en cascada. Generó el resultado, luego lo copió todo en un script y lo ejecutó. ¡Tomó una eternidad pero funcionó de maravilla! ¡Gracias!
tehbeardedone
5

Vi esta publicación cuando estaba buscando la declaración mysql para descartar todas las tablas de WordPress basadas en @Xenph Yan. Esto es lo que hice eventualmente:

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

esto le dará el conjunto de consultas para todas las tablas que comienza con wp_

talsibony
fuente
5

Aquí está mi solución:

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

Y, por supuesto, debe reemplazarlo TABLE_PREFIX_GOES_HEREcon su prefijo.

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

Editar:

sp_MSforeachtable no está documentado, por lo tanto, no es adecuado para la producción porque su comportamiento puede variar según la versión de MS_SQL.

mrosiak
fuente
Impresionante una línea! Esto debería ser votado a la cima.
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
Cade Roux
fuente
2

La respuesta de Xenph Yan fue mucho más limpia que la mía, pero aquí está la mía de todos modos .

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

Simplemente cambie tableNamea los caracteres con los que desea buscar.

FryHard
fuente
1

Esto funcionó para mí.

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;
CENIZA
fuente
0
select 'DROP TABLE ' + name from sysobjects
where type = 'U' and sysobjects.name like '%test%'

- Test es el nombre de la tabla

Shashank
fuente
esto en realidad no ejecuta nada, solo devuelve un montón de comandos.
Stealth Rabbi
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]%'
RGH
fuente
0

Sospecho que tuve que hacer una ligera derivación en la respuesta de Xenph Yan porque tenía tablas que no estaban en el esquema predeterminado.

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

En el caso de tablas temporales, es posible que desee probar

SELECT 'DROP TABLE "' + t.name + '"' 
FROM tempdb.sys.tables t
WHERE t.name LIKE '[prefix]%'
João Mergulhão
fuente