Comment supprimer plusieurs tables avec un préfixe commun dans une seule requête?

17

J'utilise Microsoft SQL Server 2008. Ma question est: comment supprimer plusieurs tables avec un préfixe commun dans une seule requête?

quelque chose comme ça les noms de table:

LG_001_01_STLINE, 
LG_001_02_STFICHE
Violoncelle
la source

Réponses:

32

Vous pouvez créer une chaîne à l'aide des vues de catalogue, par exemple:

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 'LG_001%';

PRINT @sql;
-- EXEC sp_executesql @sql;

Bien sûr, il existe des problèmes potentiels, par exemple si ces tables ont des relations de clé étrangère, vous devrez d'abord les supprimer ou organiser la sortie pour supprimer les tables dans un certain ordre.

Pour obtenir simplement la liste des tableaux, utilisez:

SELECT s.name, t.name 
  FROM sys.tables AS t 
  INNER JOIN sys.schemas AS s 
  ON t.[schema_id] = s.[schema_id] 
  WHERE t.name LIKE 'LG_001%';
Aaron Bertrand
la source
Merci beaucoup de vous être souvenu de "organiser la sortie pour supprimer les tables dans un certain ordre"!
sdlins
4

J'ai exécuté cette requête, puis collé les résultats dans la fenêtre de requête pour supprimer toutes les tables:

SELECT 'DROP TABLE ' + NAME from sys.tables
ORDER BY NAME

Si vous souhaitez supprimer toutes les tables mais conserver celles dont le nom commence par A, B, C ou D:

SELECT 'DROP TABLE ' + NAME from sys.tables
WHERE NAME NOT LIKE '[ABCD]%'
GROUP BY NAME
Mike
la source
-1

Cela vous permet de supprimer un nombre beaucoup plus grand de tables.

declare 
@cursor as cursor, 
@FTABLE as varchar(500) 
set @cursor = CURSOR FOR 
select 'drop table ' + NAME + ';' 
from sys.tables 
where not SUBSTRING(NAME,10,3) in 
( 
'310', 
'311', 
'312', 
'313', 
'314', 
'320', 
'321', 
'322' 
) 
open @cursor 
fetch next from @cursor into @FTABLE 
while (@@FETCH_STATUS =0) 
begin 
        exec(@FTABLE) 
        print @FTABLE 
fetch next from @cursor into @FTABLE 
end 
close @cursor 
deallocate @cursor 
Mel
la source
2
Plus grand que quoi? Pourriez-vous modifier votre SQL pour qu'il recherche des tables avec un préfixe commun, comme l'OP l'a demandé?
dezso
-1

J'aime celui que j'ai écrit:

  DECLARE @chv_LG001_TableName nvarchar (100)
  DECLARE @chv_DROP_LG001_Tables nvarchar(100)
  DECLARE @chv_LG001_Table_Count int

  SET @chv_LG001_Table_Count = (SELECT count(OBJECT_NAME(id))
        FROM SYSINDEXES
        WHERE OBJECTPROPERTY(id,'isUserTable')=1 AND indid < 2
            and OBJECT_NAME(id) like 'LG_001%')

 IF @chv_LG001_Table_Count > 0
    BEGIN

    DECLARE  Drop_LG001_Tables_Cursor CURSOR FOR
      -- This query will give you the table list you are wanting
        SELECT OBJECT_NAME(id)
        FROM SYSINDEXES
        WHERE OBJECTPROPERTY(id,'isUserTable')=1 AND indid < 2
            and OBJECT_NAME(id) like 'LG_001%'

    OPEN Drop_LG001_Tables_Cursor
    FETCH NEXT FROM Drop_LG001_Tables_Cursor INTO @chv_LG001_TableName 
    WHILE @@FETCH_STATUS = 0 

    BEGIN           

    SET @chv_DROP_LG001_Tables = 'DROP TABLE ' + '[' + @chv_LG001_TableName + ']'

    --Print @chv_DROP_LG001_Tables 
-- Uncomment the next line when you are ready because it WILL clear out these tables. 
    --EXEC sp_executesql @chv_DROP_LG001_Tables

    FETCH NEXT FROM Drop_LG001_Tables_Cursor
    INTO @chv_LG001_TableName

    END

    CLOSE Drop_LG001_Tables_Cursor
    DEALLOCATE Drop_LG001_Tables_Cursor

END
RedRaider
la source
2
Tant de problèmes ici. (1) L'échafaudage du curseur est complexe et inutile. (2) Lorsque vous utilisez un curseur Firehose, vous devez au moins utiliser STATICet / ou LOCAL FAST_FORWARD] ( sqlperformance.com/2012/09/t-sql-queries/cursor-options ). (3) Vous ne devez pas utiliser des vues obsolètes à compatibilité descendante comme sysindexes. (4) Votre script suppose que toutes les tables sont dans le dboschéma (ou pire, le schéma par défaut de l'utilisateur en cours d'exécution, qui peut ne pas l'être dbo).
Aaron Bertrand
-2

Cela peut être fait en utilisant executecomme suit:

declare @sql1 nvarchar(max) 
SELECT @sql1 =
 STUFF(
  (
    select ' drop table dbo.[' + name + ']'

FROM         sys.sysobjects AS sobjects
WHERE     (xtype = 'U') AND (name LIKE 'GROUP_BASE_NEW_WORK_%')
        for xml path('')
   ),
        1,1,'')

        execute sp_executesql @sql1
sharonw
la source
1
Il s'agit essentiellement d'une variation, mais sans aucune amélioration, de la réponse acceptée. La différence est simplement que vous avez choisi de supposer que 1) le schéma par défaut est censé être dbo, et 2) les noms ne peuvent jamais contenir un ]- qui peuvent tous deux être vrais dans le cas de l'OP mais ce serait quand même un bon idée de mentionner ces hypothèses, car les mises en garde qui en découlent pourraient ne pas être tout à fait évidentes pour les autres. Pourtant, comme je l'ai dit au début, mon principal problème avec cette réponse est qu'elle reformule simplement une suggestion déjà existante sans ajouter de nouvelle valeur.
Andriy M
-3
SELECT s.name, t.name 
  FROM sys.tables AS t 
  INNER JOIN sys.schemas AS s 
  ON t.[schema_id] = s.[schema_id] 
  WHERE t.name LIKE 'LG_001%';

Exécutez la requête ci-dessus et enregistrez les résultats dans un fichier csv. Ouvrez ensuite ce fichier CSV dans un bloc-notes. Ensuite, faites Ctrl + H pour remplacer le schéma par DROP TABLE SCHEMA qui vous donnera toutes les requêtes de dépôt, copiez et collez ce grand sql dans votre outil sql et exécutez

si vos résultats sont

myschema.table1
myschema.table2

après le remplacement, cela ressemblera à ceci

DROP TABLE MYSCHEMA.TABLE1
DROP TABLE MYSCHEMA.TABLE2
Abhijith
la source
-1 Pourquoi voudriez-vous copier / coller dans Excel et générer des commandes de dépôt? Vous pouvez facilement le faire en utilisant la PRINTdéclaration. Comment votre réponse est-elle meilleure que la réponse la plus votée?
Kin Shah