¿Cómo soltar varias tablas con prefijo común en una consulta?

17

Estoy usando Microsoft SQL Server 2008. Mi pregunta es: ¿Cómo soltar varias tablas con un prefijo común en una consulta?

algo así como los nombres de las tablas:

LG_001_01_STLINE, 
LG_001_02_STFICHE
Violonchelo
fuente

Respuestas:

32

Puede construir una cadena usando las vistas de catálogo, por ejemplo:

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;

Por supuesto, hay posibles problemas, por ejemplo, si estas tablas tienen relaciones de clave externa, deberá descartarlas primero u organizar la salida para descartar las tablas en un orden determinado.

Para obtener la lista de tablas, 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
fuente
¡Muchas gracias por recordar sobre "organizar la salida para colocar las tablas en un orden determinado"!
sdlins
4

Ejecuté esta consulta y luego pegué los resultados en la ventana de consulta para descartar todas las tablas:

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

Si desea eliminar todas las tablas pero mantener aquellas con nombres que comenzaron con A, B, C o D:

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

Esto le permite eliminar una cantidad mucho mayor de tablas.

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
fuente
2
¿Mayor que qué? ¿Podría modificar su SQL para que busque tablas con un prefijo común, como OP solicitó?
dezso
-1

Me gusta este que escribí:

  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
fuente
2
Tantos problemas aquí. (1) El andamio del cursor es complejo e innecesario. (2) Cuando utiliza un cursor de firehose, al menos debe usar STATICy / o LOCAL FAST_FORWARD] ( sqlperformance.com/2012/09/t-sql-queries/cursor-options ). (3) No debería utilizar vistas de compatibilidad con versiones anteriores obsoletas como sysindexes. (4) Su secuencia de comandos asume que todas las tablas están en el dboesquema (o peor, el esquema predeterminado del usuario ejecutor, que puede que ni siquiera lo esté dbo).
Aaron Bertrand
-2

Esto se puede hacer de la executesiguiente manera:

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
fuente
1
Esto es esencialmente una variación, pero sin ninguna mejora, en la respuesta aceptada. La diferencia es simplemente que ha optado por asumir que 1) se supone que el esquema predeterminado es dbo, y 2) los nombres nunca pueden contener un ]- ambos pueden ser ciertos en el caso del OP pero aún así sería un buen idea mencionar esos supuestos, porque las advertencias que se derivan de ellos podrían no ser del todo obvias para otras personas. Aún así, como dije al principio, mi problema principal con esta respuesta es que simplemente repite una sugerencia ya existente sin agregar ningún valor nuevo.
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%';

Ejecute la consulta anterior y guarde los resultados en un csv. Luego abra ese CSV en un bloc de notas. Luego haga Ctrl + H para reemplazar el esquema con DROP TABLE SCHEMA que le dará todas las consultas de caída, copie y pegue este gran sql en su herramienta sql y ejecute

si tus resultados son

myschema.table1
myschema.table2

después de reemplazar, se verá así

DROP TABLE MYSCHEMA.TABLE1
DROP TABLE MYSCHEMA.TABLE2
Abhijith
fuente
-1 ¿Por qué copiar / pegar en Excel y generar comandos de soltar? Puedes hacerlo fácilmente usando una PRINTdeclaración. ¿Cómo es tu respuesta mejor que la respuesta más votada?
Kin Shah