Como descartar várias tabelas com prefixo comum em uma consulta?

17

Estou usando o Microsoft SQL Server 2008. Minha pergunta é: Como descartar várias tabelas com prefixo comum em uma consulta?

algo como os nomes das tabelas:

LG_001_01_STLINE, 
LG_001_02_STFICHE
Violoncelo
fonte

Respostas:

32

Você pode criar uma string usando as visualizações de catálogo, por exemplo:

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;

É claro que existem dicas em potencial, por exemplo, se essas tabelas tiverem relações de chave estrangeira, você precisará descartá-las primeiro ou organizar a saída para descartá-las em uma determinada ordem.

Para obter apenas a lista de tabelas, use:

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
fonte
Muito obrigado por se lembrar de "organizar a saída para soltar as tabelas em uma determinada ordem"!
Sdlins 23/05/19
4

Eu executei essa consulta e colei os resultados novamente na janela de consulta para soltar todas as tabelas:

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

Se você deseja excluir todas as tabelas, mas mantenha aquelas com nomes que começaram com A, B, C ou D:

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

Isso permite excluir um número muito maior de tabelas.

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
fonte
2
Maior que o que? Você poderia modificar seu SQL para procurar tabelas com um prefixo comum, como o OP pediu?
Dezso
-1

Eu gosto deste que eu escrevi:

  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
fonte
2
Tantas questões aqui. (1) O andaime do cursor é complexo e desnecessário. (2) Ao usar um cursor de mangueira de incêndio, você deve pelo menos usar STATICe / ou LOCAL FAST_FORWARD] ( sqlperformance.com/2012/09/t-sql-queries/cursor-options ). (3) Você não deve usar modos de exibição obsoletos e de compatibilidade com versões anteriores sysindexes. (4) Seu script assume que todas as tabelas estão no dboesquema (ou pior, o esquema padrão do usuário em execução, que pode até não estar dbo).
Aaron Bertrand
-2

Isso pode ser feito da executeseguinte maneira:

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
fonte
11
Isso é essencialmente uma variação, mas sem nenhuma melhoria, da resposta aceita. A diferença é apenas que você escolheu assumir que 1) o esquema padrão deveria ser dboe 2) os nomes nunca podem conter um ]- os quais podem muito bem ser verdade no caso do OP, mas ainda assim seria bom É recomendável mencionar essas suposições, porque as advertências que se seguem podem não ser totalmente óbvias para outras pessoas. Ainda assim, como eu disse no começo, meu principal problema com esta resposta é que ela apenas reafirma uma sugestão já existente sem agregar nenhum novo valor.
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%';

Execute a consulta acima e salve os resultados em um csv. Em seguida, abra esse CSV em um bloco de notas. Em seguida, pressione Ctrl + H para substituir o esquema pelo DROP TABLE SCHEMA, que fornecerá todas as consultas suspensas, copie e cole esse grande sql em sua ferramenta sql e execute

se seus resultados forem

myschema.table1
myschema.table2

depois de substituir, ficará assim

DROP TABLE MYSCHEMA.TABLE1
DROP TABLE MYSCHEMA.TABLE2
Abhijith
fonte
-1 Por que você copia / cola no Excel e gera comandos drop? Você pode fazer isso facilmente usando a PRINTinstrução Como sua resposta é melhor que a resposta mais votada?
Kin Shah