Elimina tutte le tabelle i cui nomi iniziano con una determinata stringa
-
08-06-2019 - |
Domanda
Vorrei uno script per eliminare tutte le tabelle il cui nome inizia con una determinata stringa.Sono sicuro che questo può essere fatto con alcuni SQL dinamici e il INFORMATION_SCHEMA
tavoli.
Se qualcuno ha uno script, o riesce a crearne uno velocemente, lo pubblichi.
Se nessuno pubblica una risposta prima che io la capisca da solo, pubblicherò la mia soluzione.
Soluzione
Potrebbe essere necessario modificare la query per includere il proprietario se ce n'è più di uno nel database.
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
Questo è più pulito rispetto all'utilizzo di un approccio in due passaggi di generazione di script ed esecuzione.Ma un vantaggio della generazione dello script è che ti dà la possibilità di rivedere l'intero ciò che verrà eseguito prima che venga effettivamente eseguito.
So che se dovessi farlo su un database di produzione, starei il più attento possibile.
Modificare Esempio di codice corretto.
Altri suggerimenti
SELECT 'DROP TABLE "' + TABLE_NAME + '"'
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '[prefix]%'
Questo genererà uno script.
Aggiunta di una clausola per verificare l'esistenza della tabella prima dell'eliminazione:
SELECT 'IF OBJECT_ID(''' +TABLE_NAME + ''') IS NOT NULL BEGIN DROP TABLE [' + TABLE_NAME + '] END;'
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '[prefix]%'
Ciò ti consentirà di ottenere le tabelle in ordine di chiave esterna ed eviterà di eliminare alcune delle tabelle create da SQL Server.IL t.Ordinal
Il valore suddividerà le tabelle in livelli di dipendenza.
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
Su Oracle XE funziona:
SELECT 'DROP TABLE "' || TABLE_NAME || '";'
FROM USER_TABLES
WHERE TABLE_NAME LIKE 'YOURTABLEPREFIX%'
O se vuoi rimuovere i vincoli e liberare spazio inoltre, usa questo:
SELECT 'DROP TABLE "' || TABLE_NAME || '" cascade constraints PURGE;'
FROM USER_TABLES
WHERE TABLE_NAME LIKE 'YOURTABLEPREFIX%'
Che genererà un sacco di DROP TABLE cascade constraints PURGE
dichiarazioni...
Per VIEWS
Usa questo:
SELECT 'DROP VIEW "' || VIEW_NAME || '";'
FROM USER_VIEWS
WHERE VIEW_NAME LIKE 'YOURVIEWPREFIX%'
EXEC sp_MSforeachtable 'if PARSENAME("?",1) like ''%CertainString%'' DROP TABLE ?'
Modificare:
sp_MSforeachtable non è documentato, quindi non è adatto alla produzione perché il suo comportamento può variare a seconda della versione di MS_SQL.
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
Ho visto questo post mentre cercavo l'istruzione mysql per eliminare tutte le tabelle WordPress basate su @Xenph Yan ecco cosa ho fatto alla fine:
SELECT CONCAT( 'DROP TABLE `', TABLE_NAME, '`;' ) AS query
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'wp_%'
questo ti darà l'insieme di query di rilascio per tutte le tabelle che iniziano con wp_
Ecco la mia soluzione:
SELECT CONCAT('DROP TABLE `', TABLE_NAME,'`;')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'TABLE_PREFIX_GOES_HERE%';
E ovviamente devi sostituirlo TABLE_PREFIX_GOES_HERE
con il tuo prefisso
Xenph YanLa risposta di è stata molto più pulita della mia, ma ecco la mia lo stesso.
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
Cambia e basta tableName
ai caratteri con cui vuoi effettuare la ricerca.
Grazie Curt, è lo stesso tipo di soluzione che avevo a metà strada.
Il tuo però è più carino del mio: si presta a facili modifiche.Ho aggiunto un'unione alla selezione e ho cancellato anche alcune visualizzazioni ;)
declare @cmd varchar(4000)
declare cmds cursor for
Select 'drop table [' + Table_Name + ']'
From INFORMATION_SCHEMA.TABLES
Where Table_Name like 'prefix%'
union
Select 'drop view [' + Table_Name + ']'
From INFORMATION_SCHEMA.VIEWS
Where Table_Name like 'prefix%'
open cmds
while 1=1
begin
fetch cmds into @cmd
if @@fetch_status != 0 break
exec(@cmd)
end
close local
deallocate local
Non preoccuparti, non è un database di produzione: serve solo per pulire facilmente il mio database di sviluppo mentre provo le cose.
select 'DROP TABLE ' + name from sysobjects
where type = 'U' and sysobjects.name like '%test%'
-- Test è il nome della tabella
SELECT 'if object_id(''' + TABLE_NAME + ''') is not null begin drop table "' + TABLE_NAME + '" end;'
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '[prefix]%'
Ho dovuto fare una leggera derivazione sulla risposta di Xenph Yan, sospetto perché avevo tabelle non nello schema predefinito.
SELECT 'DROP TABLE Databasename.schema.' + TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'strmatch%'
In caso di tabelle temporanee, potresti provare
SELECT 'DROP TABLE "' + t.name + '"'
FROM tempdb.sys.tables t
WHERE t.name LIKE '[prefix]%'