Löschen Sie alle Tabellen, deren Namen mit einer bestimmten Zeichenfolge beginnen

150

Wie kann ich alle Tabellen löschen, deren Namen mit einer bestimmten Zeichenfolge beginnen?

Ich denke, dass dies mit etwas dynamischem SQL und den INFORMATION_SCHEMATabellen möglich ist.

Blorgbeard ist raus
quelle

Antworten:

151

Möglicherweise müssen Sie die Abfrage so ändern, dass sie den Eigentümer enthält, wenn die Datenbank mehr als eine enthält.

DECLARE @cmd varchar(4000)
DECLARE cmds CURSOR FOR
SELECT 'drop table [' + Table_Name + ']'
FROM INFORMATION_SCHEMA.TABLES
WHERE Table_Name LIKE 'prefix%'

OPEN cmds
WHILE 1 = 1
BEGIN
    FETCH cmds INTO @cmd
    IF @@fetch_status != 0 BREAK
    EXEC(@cmd)
END
CLOSE cmds;
DEALLOCATE cmds

Dies ist sauberer als die Verwendung eines zweistufigen Ansatzes zum Generieren von Skripten plus Ausführen. Ein Vorteil der Skriptgenerierung besteht jedoch darin, dass Sie die Möglichkeit haben, die gesamte Ausführung zu überprüfen, bevor sie tatsächlich ausgeführt wird.

Ich weiß, wenn ich dies gegen eine Produktionsdatenbank tun würde, wäre ich so vorsichtig wie möglich.

Codebeispiel bearbeiten behoben.

Curt Hagenlocher
quelle
5
Möglicherweise müssen Sie dieses Skript aufgrund von Fremdschlüsseleinschränkungen zwischen Master- und Detailtabellen mehrmals ausführen.
Alexander Prokofyev
7
In SQL Server 2005 musste ich die letzten beiden Zeilen in ändern close cmds; deallocate cmds.
Hamish Grubijan
Warnung : Diese Lösung kann auch von SQL Server erstellte Tabellen löschen! Meine folgende Lösung vermeidet dies und löscht Tabellen in der Reihenfolge der Fremdschlüsselabhängigkeit.
Tony O'Hagan
Das hat bei mir nicht funktioniert. Die Antwort auf diese Frage hat funktioniert: stackoverflow.com/questions/5116296/…
Ayushmati
115
SELECT 'DROP TABLE "' + TABLE_NAME + '"' 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE '[prefix]%'

Dadurch wird ein Skript generiert.

Hinzufügen einer Klausel, um das Vorhandensein einer Tabelle vor dem Löschen zu überprüfen:

SELECT 'IF OBJECT_ID(''' +TABLE_NAME + ''') IS NOT NULL BEGIN DROP TABLE [' + TABLE_NAME + '] END;' 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE '[prefix]%'
Xenph Yan
quelle
10
Ich könnte hinzufügen, um die Klammern zu entfernen, wenn "Präfix" durch Ihr Zielpräfix ersetzt wird.
Levitikon
10
MYSQL: SELECT concat ('DROP TABLE', TABLE_NAME, ";") als Daten FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE '[Präfix]%' --- für diejenigen, die mich mögen, fand diesen Thread
Andre
1
Das Ergebnis enthält auch Ansichten
Ondra
1
Vergessen Sie nicht, _ zu entkommen, wenn dies Teil Ihres Präfixes ist, z. WHERE TABLE_NAME LIKE 'em\_%' ESCAPE '\';
EM0
3
Dies erzeugt ein Skript, aber wie führt man das Skript aus?
daOnlyBG
16

Dadurch erhalten Sie die Tabellen in der Reihenfolge der Fremdschlüssel und können einige der von SQL Server erstellten Tabellen nicht löschen. Der t.OrdinalWert schneidet die Tabellen in Abhängigkeitsebenen.

WITH TablesCTE(SchemaName, TableName, TableID, Ordinal) AS
(
    SELECT OBJECT_SCHEMA_NAME(so.object_id) AS SchemaName,
        OBJECT_NAME(so.object_id) AS TableName,
        so.object_id AS TableID,
        0 AS Ordinal
    FROM sys.objects AS so
    WHERE so.type = 'U'
        AND so.is_ms_Shipped = 0
        AND OBJECT_NAME(so.object_id)
        LIKE 'MyPrefix%'

    UNION ALL
    SELECT OBJECT_SCHEMA_NAME(so.object_id) AS SchemaName,
        OBJECT_NAME(so.object_id) AS TableName,
        so.object_id AS TableID,
        tt.Ordinal + 1 AS Ordinal
    FROM sys.objects AS so
        INNER JOIN sys.foreign_keys AS f
            ON f.parent_object_id = so.object_id
                AND f.parent_object_id != f.referenced_object_id
        INNER JOIN TablesCTE AS tt
            ON f.referenced_object_id = tt.TableID
    WHERE so.type = 'U'
        AND so.is_ms_Shipped = 0
        AND OBJECT_NAME(so.object_id)
        LIKE 'MyPrefix%'
)
SELECT DISTINCT t.Ordinal, t.SchemaName, t.TableName, t.TableID
FROM TablesCTE AS t
    INNER JOIN
    (
        SELECT
            itt.SchemaName AS SchemaName,
            itt.TableName AS TableName,
            itt.TableID AS TableID,
            Max(itt.Ordinal) AS Ordinal
        FROM TablesCTE AS itt
        GROUP BY itt.SchemaName, itt.TableName, itt.TableID
    ) AS tt
        ON t.TableID = tt.TableID
            AND t.Ordinal = tt.Ordinal
ORDER BY t.Ordinal DESC, t.TableName ASC
Tony O'Hagan
quelle
Vielen Dank an stackoverflow.com/questions/352176/…
Tony O'Hagan
3
Schnellkorrektur: TableName erscheint einige Male in WHERE-Klauseln und sollte durch OBJECT_NAME (so.object_id) ersetzt werden. Schönes Skript!
Witz
6

Unter Oracle XE funktioniert dies:

SELECT 'DROP TABLE "' || TABLE_NAME || '";'
FROM USER_TABLES
WHERE TABLE_NAME LIKE 'YOURTABLEPREFIX%'

Oder wenn Sie die Einschränkungen entfernen und auch Speicherplatz freigeben möchten , verwenden Sie Folgendes:

SELECT 'DROP TABLE "' || TABLE_NAME || '" cascade constraints PURGE;'
FROM USER_TABLES
WHERE TABLE_NAME LIKE 'YOURTABLEPREFIX%'

Welches wird eine Reihe von DROP TABLE cascade constraints PURGEAussagen generieren ...

Zur VIEWSVerwendung:

SELECT 'DROP VIEW "' || VIEW_NAME || '";'
FROM USER_VIEWS
WHERE VIEW_NAME LIKE 'YOURVIEWPREFIX%'
Rosdi Kasim
quelle
Hat perfekt funktioniert. Hatte 61.037 leere Tabellen zum Löschen aus einer für die Qualitätssicherung verwendeten Datenbank. Ich habe das Beispiel für Kaskadeneinschränkungen verwendet. Generierte die Ausgabe, kopierte alles in ein Skript und führte es aus. Hat ewig gedauert, aber es hat wie ein Zauber funktioniert! Vielen Dank!
Tehbeardedone
5

Ich habe diesen Beitrag gesehen, als ich nach einer MySQL-Anweisung gesucht habe, um alle WordPress-Tabellen basierend auf @Xenph Yan zu löschen. Hier ist, was ich letztendlich getan habe:

SELECT CONCAT(  'DROP TABLE `', TABLE_NAME,  '`;' ) AS query
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE  'wp_%'

Dadurch erhalten Sie die Drop-Abfragen für alle Tabellen, die mit wp_ beginnen

Talsibony
quelle
5

Hier ist meine Lösung:

SELECT CONCAT('DROP TABLE `', TABLE_NAME,'`;') 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE 'TABLE_PREFIX_GOES_HERE%';

Und natürlich müssen Sie durch TABLE_PREFIX_GOES_HEREIhr Präfix ersetzen .

vencedor
quelle
5
EXEC sp_MSforeachtable 'if PARSENAME("?",1) like ''%CertainString%'' DROP TABLE ?'

Bearbeiten:

sp_MSforeachtable ist nicht dokumentiert und daher nicht für die Produktion geeignet, da sein Verhalten je nach MS_SQL-Version variieren kann.

mrosiak
quelle
Super Einzeiler! Dies sollte nach oben abgestimmt werden.
user3413723
4
CREATE PROCEDURE usp_GenerateDROP
    @Pattern AS varchar(255)
    ,@PrintQuery AS bit
    ,@ExecQuery AS bit
AS
BEGIN
    DECLARE @sql AS varchar(max)

    SELECT @sql = COALESCE(@sql, '') + 'DROP TABLE [' + TABLE_NAME + ']' + CHAR(13) + CHAR(10)
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_NAME LIKE @Pattern

    IF @PrintQuery = 1 PRINT @sql
    IF @ExecQuery = 1 EXEC (@sql)
END
Cade Roux
quelle
2

Xenph Yans Antwort war viel sauberer als meine, aber hier ist meine trotzdem.

DECLARE @startStr AS Varchar (20)
SET @startStr = 'tableName'

DECLARE @startStrLen AS int
SELECT @startStrLen = LEN(@startStr)

SELECT 'DROP TABLE ' + name FROM sysobjects
WHERE type = 'U' AND LEFT(name, @startStrLen) = @startStr

Wechseln tableNameSie einfach zu den Zeichen, mit denen Sie suchen möchten.

FryHard
quelle
1

Das hat bei mir funktioniert.

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

PRINT @sql;
-- EXEC sp_executesql @sql;
ASCHE
quelle
0
select 'DROP TABLE ' + name from sysobjects
where type = 'U' and sysobjects.name like '%test%'

- Test ist der Tabellenname

Shashank
quelle
Dies führt eigentlich nichts aus, sondern gibt nur eine Reihe von Befehlen zurück.
Stealth Rabbi
0
SELECT 'if object_id(''' + TABLE_NAME + ''') is not null begin drop table "' + TABLE_NAME + '" end;' 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE '[prefix]%'
RGH
quelle
0

Ich musste eine leichte Ableitung von Xenph Yans Antwort vornehmen, die ich vermute, weil ich Tabellen hatte, die nicht im Standardschema waren.

SELECT 'DROP TABLE Databasename.schema.' + TABLE_NAME 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE 'strmatch%'
Xaxum
quelle
0

Bei temporären Tabellen möchten Sie es möglicherweise versuchen

SELECT 'DROP TABLE "' + t.name + '"' 
FROM tempdb.sys.tables t
WHERE t.name LIKE '[prefix]%'
João Mergulhão
quelle