Удалите все таблицы, имена которых начинаются с определенной строки

Как удалить все таблицы, имена которых начинаются с заданной строки?

Я думаю, что это можно сделать с помощью динамического SQL и таблиц INFORMATION_SCHEMA.

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
155
0
214 617
15
Перейти к ответу Данный вопрос помечен как решенный

Ответы 15

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

Я мог бы добавить, чтобы убрать скобки при замене «префикса» на ваш целевой префикс.

Levitikon 20.05.2012 19:31

MYSQL: SELECT concat ('DROP TABLE', TABLE_NAME, ";") as data FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE '[prefix]%' --- для тех, кто, как я, нашел эту тему

Andre 06.11.2012 04:27

Результат также содержит просмотры

Ondra 29.03.2013 17:01

Не забудьте экранировать _, если это часть вашего префикса, например. WHERE TABLE_NAME LIKE 'em\_%' ESCAPE '\';

EM0 29.09.2015 17:37

Это создает сценарий, но как его выполнить?

daOnlyBG 04.08.2017 23:45

Потрясающие! Мне очень нравится подход «сначала сценарий», так что я мог видеть, что упадет, а не просто выполнить. Супер полезное спасибо !!

hardba11 23.03.2018 20:54

В этом рабочем процессе выполните сценарий, выделив полный выходной столбец, скопируйте и вставьте его в окно запроса. Идея состоит в том, чтобы вручную просмотреть каждую строку и, возможно, изменить перед выполнением отбрасывания.

Larryjl 24.11.2020 00:17

Ответ Ксенф Ян был намного чище, чем мой, но вот мой все равно.

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

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

Это чище, чем использование двухэтапного подхода «генерация скрипта плюс запуск». Но одним из преимуществ генерации сценария является то, что он дает вам возможность полностью просмотреть то, что будет запускаться, прежде чем оно будет запущено на самом деле.

Я знаю, что если бы я собирался сделать это с производственной базой данных, я был бы максимально осторожен.

Редактировать Пример кода исправлен.

Возможно, вам придется запускать этот сценарий несколько раз из-за ограничений внешнего ключа между главной и подробной таблицами.

Alexander Prokofyev 26.12.2008 08:24

В SQL Server 2005 мне пришлось изменить две последние строки на close cmds; deallocate cmds.

Hamish Grubijan 26.04.2011 18:08
Предупреждение: This solution may also delete tables created by SQL Server! My solution below avoids this and deletes tables in foreign key dependency order.
Tony O'Hagan 19.07.2015 04:15

У меня это не сработало. Ответ на этот вопрос сработал: stackoverflow.com/questions/5116296/…

Ayushmati 11.05.2020 22:18

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

select 'DROP TABLE ' + name from sysobjects
where type = 'U' and sysobjects.name like '%test%'

- Test - это имя таблицы

на самом деле это ничего не выполняет, просто возвращает кучу команд.

Stealth Rabbi 12.03.2014 20:57

Это позволит вам расположить таблицы в порядке внешнего ключа и избежать отбрасывания некоторых таблиц, созданных 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

Спасибо stackoverflow.com/questions/352176/…

Tony O'Hagan 10.02.2014 12:08

Быстрое исправление: TableName несколько раз появляется в предложениях WHERE, и его следует заменить на OBJECT_NAME (so.object_id). Хороший сценарий!

witttness 23.09.2014 07:18

SELECT 'if object_id(''' + TABLE_NAME + ''') is not null begin drop table "' + TABLE_NAME + '" end;' 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE '[prefix]%'

Я подозреваю, что мне пришлось сделать небольшой вывод по ответу Ксенфа Яна, потому что у меня были таблицы, не входящие в схему по умолчанию.

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

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

Сработало отлично. Пришлось удалить 61 037 пустых таблиц из базы данных, используемой для контроля качества. Я использовал пример каскадных ограничений. Сгенерировал вывод, затем скопировал все в сценарий и запустил его. Принял навсегда, но это сработало как шарм! Спасибо!

tehbeardedone 30.10.2019 19:52

Я увидел этот пост, когда искал инструкцию mysql для удаления всех таблиц WordPress на основе @Xenph Yan, вот что я в итоге сделал:

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 своим префиксом.

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

Редактировать:

sp_MSforeachtable недокументирована, поэтому не подходит для производства, поскольку ее поведение может варьироваться в зависимости от версии MS_SQL.

Потрясающий однострочник! Это должно быть поставлено на первое место.

user3413723 20.12.2017 20:17

В случае временных таблиц вы можете попробовать

SELECT 'DROP TABLE "' + t.name + '"' 
FROM tempdb.sys.tables t
WHERE t.name LIKE '[prefix]%'

Это сработало для меня.

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;

Я хотел бы опубликовать свое предложение о решении, которое DROP (а не просто генерирует и выбирает команды drop) все таблицы на основе подстановочного знака (например, «table_20210114») старше определенного количества дней.

DECLARE 
    @drop_command NVARCHAR(MAX) = '',
    @system_time date,
    @table_date nvarchar(8),
    @older_than int = 7
    
Set @system_time = (select getdate() - @older_than)
Set @table_date = (SELECT CONVERT(char(8), @system_time, 112))

SELECT @drop_command += N'DROP TABLE ' + QUOTENAME(SCHEMA_NAME(schema_id)) + '.' + QUOTENAME([Name]) + ';'
FROM <your_database_name>.sys.tables
WHERE [Name] LIKE 'table_%' AND RIGHT([Name],8) < @table_date

SELECT @drop_command
 
EXEC sp_executesql @drop_command

Другие вопросы по теме