Come eliminare più tabelle con prefisso comune in una query?


17

Sto utilizzando Microsoft SQL Server 2008. La mia domanda è: come eliminare più tabelle con prefisso comune in una query?

qualcosa come i nomi di quella tabella:

LG_001_01_STLINE, 
LG_001_02_STFICHE

Risposte:


32

Puoi creare una stringa usando le viste del catalogo, ad esempio:

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;

Ovviamente ci sono potenziali gotcha, ad esempio se queste tabelle hanno relazioni di chiave esterna, dovrai prima lasciarle cadere, o disporre l'output per far cadere le tabelle in un certo ordine.

Per ottenere l'elenco delle tabelle, utilizzare:

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

Grazie mille per esserti ricordato di "organizza l'output per far cadere le tabelle in un certo ordine"!
sdlins,

4

Ho eseguito questa query, quindi ho incollato i risultati nella finestra della query per eliminare tutte le tabelle:

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

Se si desidera eliminare tutte le tabelle ma conservare quelle con nomi che sono iniziati con A, B, C o D:

SELECT 'DROP TABLE ' + NAME from sys.tables
WHERE NAME NOT LIKE '[ABCD]%'
GROUP BY NAME

-1

Ciò consente di eliminare un numero molto maggiore di tabelle.

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 

2
Più grande di cosa? Potresti modificare il tuo SQL in modo che cerchi le tabelle con un prefisso comune, come richiesto da OP?
dezso

-1

Mi piace questo che ho scritto:

  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

2
Così tanti problemi qui. (1) Il ponteggio del cursore è complesso e non necessario. (2) Quando si utilizza un cursore firehose, è necessario almeno utilizzare STATICe / o LOCAL FAST_FORWARD] ( sqlperformance.com/2012/09/t-sql-queries/cursor-options ). (3) Non dovresti usare viste di compatibilità obsolete e obsolete come sysindexes. (4) Lo script presuppone che tutte le tabelle siano nello dboschema (o peggio, lo schema predefinito dell'utente che esegue, che potrebbe anche non esserlo dbo).
Aaron Bertrand

-2

Questo può essere fatto usando executecome segue:

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

1
Questa è essenzialmente una variazione, ma senza alcun miglioramento, sulla risposta accettata. La differenza è semplicemente che hai scelto di presumere che 1) lo schema predefinito dovrebbe essere dbo, e 2) i nomi non possono mai contenere un ]- entrambi i quali potrebbero essere veri nel caso del PO ma sarebbe comunque un buon idea di menzionare quei presupposti, perché le avvertenze che ne derivano potrebbero non essere del tutto ovvie per le altre persone. Tuttavia, come ho detto all'inizio, il mio problema principale con questa risposta è che riafferma un suggerimento già esistente senza aggiungere alcun nuovo valore.
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%';

Esegui sopra la query e salva i risultati in un csv. Quindi apri quel CSV in un blocco note. Quindi fai Ctrl + H per sostituire lo schema con DROP TABLE SCHEMA che ti darà tutte le query di rilascio, copia e incolla questo grande sql nel tuo strumento sql ed esegui

se i tuoi risultati lo sono

myschema.table1
myschema.table2

dopo la sostituzione, sarà simile a questo

DROP TABLE MYSCHEMA.TABLE1
DROP TABLE MYSCHEMA.TABLE2

-1 Perché dovresti copiare / incollare in Excel e generare comandi di rilascio? Puoi farlo facilmente usando l' PRINTistruzione. In che modo la tua risposta è migliore della risposta più votata?
Kin Shah,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.