Як видалити кілька таблиць із загальним префіксом в одному запиті?


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 так, щоб він шукав таблиці із загальним префіксом, як запитував ОП?
dezso

-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) Якщо ви користуєтесь курсором, що має fireless , вам слід принаймні використовувати 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) імена ніколи не можуть містити ]- обидва ці випадки можуть бути правдивими у випадку ОП, але все-таки це було б добре ідея згадати ці припущення, тому що застереження, які випливають з них, можуть бути не зовсім очевидні для інших людей. Однак, як я вже говорив на початку, головна проблема з цією відповіддю полягає в тому, що він просто перезапускає вже існуючу пропозицію, не додаючи жодної нової цінності.
Андрій М

-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 та генерували команди drop? Ви можете легко зробити це за допомогою PRINTоператора. Як ваша відповідь краща за найвищу відповідь?
Кін Шах
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.