Как отбросить несколько таблиц с общим префиксом в одном запросе?


17

Я использую Microsoft SQL Server 2008. Мой вопрос: как отбросить несколько таблиц с общим префиксом в одном запросе?

что-то вроде этой таблицы имен:

LG_001_01_STLINE, 
LG_001_02_STFICHE

Ответы:


32

Вы можете создать строку, используя представления каталога, например:

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;

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

Чтобы просто получить список таблиц, используйте:

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

Огромное спасибо за то, что вы помните о "организовать вывод, чтобы отбрасывать таблицы в определенном порядке"!
sdlins

4

Я запустил этот запрос, а затем вставил результаты обратно в окно запроса, чтобы удалить все таблицы:

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

Если вы хотите удалить все таблицы, но сохраните таблицы с именами, которые начинаются с A, B, C или D:

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

-1

Это позволяет вам удалить гораздо большее количество таблиц.

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
Больше чем что? Не могли бы вы изменить свой SQL так, чтобы он просматривал таблицы с общим префиксом, как запрашивал OP?
Дезсо

-1

Мне нравится тот, который я написал:

  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
Здесь так много вопросов. (1) Леса курсора сложны и не нужны. (2) Когда вы используете курсор пожарного шланга, вы должны по крайней мере использовать STATICи / или LOCAL FAST_FORWARD] ( sqlperformance.com/2012/09/t-sql-queries/cursor-options ). (3) Вы не должны использовать устаревшие представления обратной совместимости, такие как sysindexes. (4) Ваш сценарий предполагает, что все таблицы находятся в dboсхеме (или, что еще хуже, схема по умолчанию для исполняющего пользователя, чего может даже не быть dbo).
Аарон Бертран

-2

Это можно сделать 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
По сути, это вариация, но без каких-либо улучшений, принятого ответа. Разница лишь в том, что вы решили предположить, что 1) схема по умолчанию должна быть dbo, и 2) имена никогда не могут содержать a ]- оба из них вполне могут быть верными в случае OP, но это все равно будет хорошим Идея упомянуть эти предположения, потому что вытекающие из них предостережения могут быть не совсем очевидны для других людей. Тем не менее, как я сказал в начале, моя главная проблема с этим ответом заключается в том, что он просто повторяет уже существующее предложение, не добавляя никакой новой ценности.
Андрей М

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

Запустите вышеуказанный запрос и сохраните результаты в CSV. Затем откройте этот CSV в блокноте. Затем нажмите Ctrl + H, чтобы заменить схему на DROP TABLE SCHEMA, которая выдаст вам все запросы на удаление, скопируйте и вставьте этот большой sql в ваш инструмент sql и выполните

если ваши результаты

myschema.table1
myschema.table2

после замены это будет выглядеть так

DROP TABLE MYSCHEMA.TABLE1
DROP TABLE MYSCHEMA.TABLE2

-1 Зачем вам копировать / вставлять в Excel и генерировать команды удаления? Вы можете легко сделать это, используя PRINTутверждение. Чем ваш ответ лучше, чем ответ с наибольшим количеством голосов?
Кин Шах
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.