Bir sorguda ortak önek ile birden çok tablo nasıl bırakılır?


17

Microsoft SQL Server 2008 kullanıyorum. Sorum şu: Nasıl bir sorguda ortak önek ile birden çok tablo bırakmak?

tablo adları gibi bir şey:

LG_001_01_STLINE, 
LG_001_02_STFICHE

Yanıtlar:


32

Katalog görünümlerini kullanarak bir dize oluşturabilirsiniz, örneğin:

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;

Tabii ki potansiyel gotcha'lar var, örneğin bu tabloların yabancı anahtar ilişkileri varsa, önce onları bırakmanız veya çıktıyı tabloları belirli bir sırada bırakacak şekilde ayarlamanız gerekir.

Yalnızca tabloların listesini almak için şunu kullanın:

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

"Çıktıları tabloları belirli bir düzende bırakacak şekilde düzenleyin" i hatırladığınız için çok teşekkür ederiz!
sdlins

4

Bu sorguyu çalıştırdıktan sonra sonuçları tüm tabloları bırakmak için sorgu penceresine yapıştırdık:

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

Tüm tabloları silmek, ancak A, B, C veya D ile başlayan adları olan tabloları saklamak istiyorsanız:

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

-1

Bu, çok daha fazla sayıda tabloyu silmenizi sağlar.

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
Ne daha büyük? SQL'inizi, OP'nin istediği gibi ortak bir önek içeren tabloları arayacak şekilde değiştirebilir misiniz?
dezso

-1

Yazdığım bu hoşuma gitti:

  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
Burada çok fazla sorun var. (1) İmleç iskelesi karmaşık ve gereksizdir. (2) Bir itfaiye imleci kullandığınızda, en azından STATICve / veya LOCAL FAST_FORWARD] kullanmalısınız ( sqlperformance.com/2012/09/t-sql-queries/cursor-options ). (3) Gibi kullanımdan kaldırılmış, geriye dönük uyumluluk görünümleri kullanmamalısınız sysindexes. (4) Komut dosyanız, tüm tabloların dboşemada olduğunu varsayar (veya daha da kötüsü, yürütme kullanıcısının varsayılan şeması, hatta olmayabilir dbo).
Aaron Bertrand

-2

Bu, executeaşağıdaki gibi kullanılarak yapılabilir :

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
Bu aslında kabul edilen cevapta bir değişiklik, ancak herhangi bir gelişme olmadan. Fark, sadece 1) varsayılan şemanın olması gerektiğini dbove 2) adların asla içeremeyeceğini varsaymanızdır ]- her ikisi de OP'nin durumunda doğru olabilir, ancak yine de iyi olacaktır. bu varsayımlardan bahsetme fikri, çünkü onlardan sonra gelen uyarılar diğer insanlar için tamamen açık olmayabilir. Yine de, başlangıçta söylediğim gibi, bu cevapla ilgili asıl sorunum, yeni bir değer eklemeden mevcut bir öneriyi yeniden ifade etmesidir.
Andriy M

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

Yukarıdaki sorguyu çalıştırın ve sonuçları bir csv'ye kaydedin. Ardından bu CSV'yi bir not defterinde açın. Sonra şeması tüm bırakma sorgularını verecek DROP TABLE SCHEMA ile değiştirmek için Ctrl + H yapın, bu büyük sql'i kopyalayıp sql aracınıza yapıştırın ve çalıştırın

eğer sonuçlarınız

myschema.table1
myschema.table2

değiştirdikten sonra şöyle görünecek

DROP TABLE MYSCHEMA.TABLE1
DROP TABLE MYSCHEMA.TABLE2

-1 Neden Excel'de kopyala / yapıştır ve bırak komutları oluştursun? İfadeyi kullanarak kolayca yapabilirsiniz PRINT. Cevabınız en yüksek oyu alan cevaptan nasıl daha iyi?
Kin Shah
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.