Supprimer toutes les tables dont les noms commencent par une certaine chaîne

150

Comment supprimer toutes les tables dont les noms commencent par une chaîne donnée?

Je pense que cela peut être fait avec du SQL dynamique et les INFORMATION_SCHEMAtables.

Blorgbeard est sorti
la source

Réponses:

151

Vous devrez peut-être modifier la requête pour inclure le propriétaire s'il y en a plusieurs dans la base de données.

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

C'est plus propre que d'utiliser une approche en deux étapes consistant à générer un script et à exécuter. Mais l'un des avantages de la génération de script est qu'elle vous donne la possibilité de revoir l'intégralité de ce qui va être exécuté avant de l'exécuter.

Je sais que si j'allais faire cela contre une base de données de production, je serais aussi prudent que possible.

Exemple de code d' édition corrigé.

Curt Hagenlocher
la source
5
Vous devrez peut-être exécuter ce script plusieurs fois en raison de contraintes de clé étrangère entre les tables maître et détail.
Alexander Prokofyev
7
Dans SQL Server 2005, j'ai dû changer les deux dernières lignes en close cmds; deallocate cmds.
Hamish Grubijan
Attention : cette solution peut également supprimer des tables créées par SQL Server! Ma solution ci-dessous évite cela et supprime les tables dans l'ordre de dépendance des clés étrangères.
Tony O'Hagan
Cela n'a pas fonctionné pour moi. La réponse à cette question a fonctionné: stackoverflow.com/questions/5116296/…
Ayushmati
115
SELECT 'DROP TABLE "' + TABLE_NAME + '"' 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE '[prefix]%'

Cela générera un script.

Ajout d'une clause pour vérifier l'existence de la table avant de la supprimer:

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
la source
10
Je pourrais ajouter pour supprimer les crochets lors du remplacement de "préfixe" par votre préfixe cible.
Levitikon
10
MYSQL: SELECT concat ('DROP TABLE', TABLE_NAME, ";") as data FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE '[prefix]%' --- pour ceux qui comme moi ont trouvé ce fil
André
1
Le résultat contient aussi des vues
Ondra
1
N'oubliez pas d'échapper _ si cela fait partie de votre préfixe, par exemple. WHERE TABLE_NAME LIKE 'em\_%' ESCAPE '\';
EM0
3
Cela génère un script, mais comment exécuter le script?
daOnlyBG
16

Cela vous permettra d'obtenir les tables dans l'ordre des clés étrangères et d'éviter de supprimer certaines des tables créées par SQL Server. La t.Ordinalvaleur découpera les tables en couches de dépendances.

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
la source
3
Solution rapide: TableName apparaît plusieurs fois dans les clauses WHERE et doit être remplacé par OBJECT_NAME (so.object_id). Beau script!
witttness
6

Sur Oracle XE, cela fonctionne:

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

Ou si vous souhaitez supprimer les contraintes et libérer de l'espace également, utilisez ceci:

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

Ce qui générera un tas de DROP TABLE cascade constraints PURGE déclarations ...

Pour VIEWSutiliser ceci:

SELECT 'DROP VIEW "' || VIEW_NAME || '";'
FROM USER_VIEWS
WHERE VIEW_NAME LIKE 'YOURVIEWPREFIX%'
Rosdi Kasim
la source
A parfaitement fonctionné. Il y avait 61 037 tables vides à supprimer d'une base de données utilisée pour le contrôle qualité. J'ai utilisé l'exemple des contraintes en cascade. Généré la sortie puis copié le tout dans un script et l'exécute. Cela a pris une éternité mais cela a fonctionné comme un charme! Merci!
tehbeardedone
5

J'ai vu cet article lorsque je cherchais une instruction mysql pour supprimer toutes les tables WordPress basées sur @Xenph Yan, voici ce que j'ai finalement fait:

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

cela vous donnera l'ensemble des requêtes de suppression pour toutes les tables commençant par wp_

talsibony
la source
5

Voici ma solution:

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

Et bien sûr, vous devez le remplacer TABLE_PREFIX_GOES_HEREpar votre préfixe.

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

Éditer:

sp_MSforeachtable n'est pas documenté et ne convient donc pas à la production car son comportement peut varier en fonction de la version de MS_SQL.

mrosiak
la source
Super one-liner! Cela devrait être voté au sommet.
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
la source
2

La réponse de Xenph Yan était bien plus propre que la mienne mais voici la mienne tout de même.

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

Changez simplement tableNameles caractères avec lesquels vous souhaitez effectuer la recherche.

FryHard
la source
1

Cela a fonctionné pour moi.

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

- Test est le nom de la table

Shashank
la source
cela n'exécute rien, retourne juste un tas de commandes.
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
la source
0

J'ai dû faire une légère dérivation sur la réponse de Xenph Yan que je soupçonne parce que j'avais des tables qui n'étaient pas dans le schéma par défaut.

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

En cas de tables temporaires, vous voudrez peut-être essayer

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