Удалите все таблицы, имена которых начинаются с определенной строки
-
08-06-2019 - |
Вопрос
Я бы хотел, чтобы скрипт удалял все таблицы, имя которых начинается с заданной строки.Я уверен, что это можно сделать с помощью некоторого динамического sql и INFORMATION_SCHEMA
таблицы.
Если у кого-то есть сценарий или кто-то может быстро его создать, пожалуйста, опубликуйте его.
Если никто не опубликует ответ до того, как я сам с этим разберусь, я опубликую свое решение.
Решение
Возможно, вам потребуется изменить запрос, чтобы включить владельца, если в базе данных их несколько.
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
Это чище, чем использование двухэтапного подхода generate script плюс run.Но одно из преимуществ генерации скрипта заключается в том, что он дает вам возможность просмотреть все, что будет запущено, до того, как оно будет запущено на самом деле.
Я знаю, что если бы я собирался сделать это с производственной базой данных, я бы был максимально осторожен.
Редактировать Исправлен пример кода.
Другие советы
SELECT 'DROP TABLE "' + TABLE_NAME + '"'
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '[prefix]%'
Это сгенерирует скрипт.
Добавление предложения для проверки существования таблицы перед удалением:
SELECT 'IF OBJECT_ID(''' +TABLE_NAME + ''') IS NOT NULL BEGIN DROP TABLE [' + TABLE_NAME + '] END;'
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '[prefix]%'
Это позволит вам расположить таблицы в порядке внешнего ключа и избежать удаления некоторых таблиц, созданных SQL Server.Тот Самый t.Ordinal
значение разделит таблицы на слои зависимостей.
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
В Oracle XE это работает:
SELECT 'DROP TABLE "' || TABLE_NAME || '";'
FROM USER_TABLES
WHERE TABLE_NAME LIKE 'YOURTABLEPREFIX%'
Или, если ты захочешь устраните ограничения и освободите место кроме того, используйте это:
SELECT 'DROP TABLE "' || TABLE_NAME || '" cascade constraints PURGE;'
FROM USER_TABLES
WHERE TABLE_NAME LIKE 'YOURTABLEPREFIX%'
Который сгенерирует кучу DROP TABLE cascade constraints PURGE
заявления...
Для VIEWS
используй это:
SELECT 'DROP VIEW "' || VIEW_NAME || '";'
FROM USER_VIEWS
WHERE VIEW_NAME LIKE 'YOURVIEWPREFIX%'
EXEC sp_MSforeachtable 'if PARSENAME("?",1) like ''%CertainString%'' DROP TABLE ?'
Редактировать:
sp_MSforeachtable недокументирован, следовательно, не подходит для производства, поскольку его поведение может варьироваться в зависимости от версии 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
Я увидел этот пост, когда искал инструкцию mysql для удаления всех таблиц WordPress на основе @Xenph. Вот что я сделал в итоге:
SELECT CONCAT( 'DROP TABLE `', TABLE_NAME, '`;' ) AS query
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'wp_%'
это даст вам набор запросов на удаление для всех таблиц, начинающихся с wp_
Вот мое решение:
SELECT CONCAT('DROP TABLE `', TABLE_NAME,'`;')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'TABLE_PREFIX_GOES_HERE%';
И, конечно же, вам нужно заменить TABLE_PREFIX_GOES_HERE
с вашей приставкой.
Ксенф Янего ответ был намного чище моего, но все равно это мой ответ.
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
Просто измени tableName
к символам, по которым вы хотите выполнить поиск.
Спасибо, Курт, это такое же решение, к которому я сам был на полпути.
Однако ваш лучше моего - он легко поддается модификации.Я добавил объединение к выбору и также удалил некоторые представления ;)
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
Не волнуйтесь, это не производственная база данных - это просто для удобства очистки моей базы данных разработчиков, пока я пробую что-то делать.
select 'DROP TABLE ' + name from sysobjects
where type = 'U' and sysobjects.name like '%test%'
-- Test - это название таблицы
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, потому что у меня были таблицы, которых не было в схеме по умолчанию.
SELECT 'DROP TABLE Databasename.schema.' + TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'strmatch%'
В случае временных таблиц, возможно, вы захотите попробовать
SELECT 'DROP TABLE "' + t.name + '"'
FROM tempdb.sys.tables t
WHERE t.name LIKE '[prefix]%'