Wie lösche ich mehrere Tabellen mit einem gemeinsamen Präfix in einer Abfrage?


17

Ich verwende Microsoft SQL Server 2008. Meine Frage lautet: Wie lösche ich mehrere Tabellen mit einem gemeinsamen Präfix in einer Abfrage?

so etwas wie die Tabellennamen:

LG_001_01_STLINE, 
LG_001_02_STFICHE

Antworten:


32

Mit den Katalogsichten können Sie einen String aufbauen, zB:

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;

Natürlich gibt es potenzielle Fallstricke. Wenn diese Tabellen beispielsweise Fremdschlüsselbeziehungen aufweisen, müssen Sie sie entweder zuerst löschen oder die Ausgabe so anordnen, dass die Tabellen in einer bestimmten Reihenfolge gelöscht werden.

Um nur die Liste der Tabellen abzurufen, verwenden Sie:

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

Vielen Dank, dass Sie sich an "Ordnen Sie die Ausgabe so an, dass die Tabellen in einer bestimmten Reihenfolge abgelegt werden" erinnert haben!
SDLINS

4

Ich habe diese Abfrage ausgeführt und dann die Ergebnisse wieder in das Abfragefenster eingefügt, um alle Tabellen zu löschen:

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

Wenn Sie alle Tabellen löschen möchten, aber die Namen beibehalten möchten, die mit A, B, C oder D beginnen:

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

-1

Auf diese Weise können Sie eine viel größere Anzahl von Tabellen löschen.

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
Größer als was? Könnten Sie Ihr SQL so ändern, dass es nach Tabellen mit einem gemeinsamen Präfix sucht, wie es OP verlangt?
Dezso

-1

Ich mag dieses, das ich schrieb:

  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
So viele Probleme hier. (1) Das Cursorgerüst ist komplex und unnötig. (2) Wenn Sie einen Firehose-Cursor verwenden, sollten Sie mindestens STATICund / oder LOCAL FAST_FORWARD] ( sqlperformance.com/2012/09/t-sql-queries/cursor-options ) verwenden. (3) Sie sollten keine veralteten, abwärtskompatiblen Ansichten wie verwenden sysindexes. (4) In Ihrem Skript wird davon ausgegangen, dass sich alle Tabellen im dboSchema befinden (oder, schlimmer noch, im Standardschema des ausführenden Benutzers, was möglicherweise gar nicht der Fall ist dbo).
Aaron Bertrand

-2

Dies kann folgendermaßen geschehen execute:

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
Dies ist im Wesentlichen eine Variation der akzeptierten Antwort, jedoch ohne Verbesserung. Der Unterschied besteht lediglich darin, dass Sie angenommen haben, dass 1) das Standardschema lauten dbosoll und 2) die Namen niemals a enthalten dürfen ]- beides mag im Fall des OP durchaus zutreffen, aber es wäre immer noch gut Erwähnen Sie diese Annahmen, da die sich daraus ergebenden Einschränkungen für andere Menschen möglicherweise nicht ganz offensichtlich sind. Wie ich zu Beginn bereits sagte, ist mein Hauptproblem bei dieser Antwort, dass nur ein bereits vorhandener Vorschlag wiederholt wird, ohne dass ein neuer Wert hinzugefügt wird.
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%';

Führen Sie die obige Abfrage aus und speichern Sie die Ergebnisse in einer CSV-Datei. Öffnen Sie dann diese CSV in einem Notizblock. Führen Sie dann Strg + H aus, um das Schema durch DROP TABLE SCHEMA zu ersetzen, das Ihnen alle Drop-Abfragen gibt. Kopieren Sie diese große SQL-Datei, fügen Sie sie in Ihr SQL-Tool ein, und führen Sie sie aus

wenn Ihre Ergebnisse sind

myschema.table1
myschema.table2

Nach dem Ersetzen sieht es so aus

DROP TABLE MYSCHEMA.TABLE1
DROP TABLE MYSCHEMA.TABLE2

-1 Warum sollten Sie in Excel kopieren / einfügen und Ablagebefehle generieren? Sie können es einfach mit PRINTAnweisung tun . Wie ist Ihre Antwort besser als die Antwort mit der höchsten Bewertung?
Kin Shah,
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.