Я використовую Microsoft SQL Server 2008. Моє запитання: як запустити кілька таблиць із загальним префіксом в одному запиті?
щось подібне до назв таблиці:
LG_001_01_STLINE,
LG_001_02_STFICHE
Я використовую Microsoft SQL Server 2008. Моє запитання: як запустити кілька таблиць із загальним префіксом в одному запиті?
щось подібне до назв таблиці:
LG_001_01_STLINE,
LG_001_02_STFICHE
Відповіді:
Ви можете створити рядок, використовуючи представлення каталогів, наприклад:
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%';
Я запустив цей запит, а потім вставив результати назад у вікно запиту, щоб скинути всі таблиці:
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
Це дозволяє видалити значно більшу кількість таблиць.
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
Мені подобається цей, який я написав:
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
STATIC
та / або LOCAL FAST_FORWARD
] ( sqlperformance.com/2012/09/t-sql-queries/cursor-options ). (3) Ви не повинні використовувати застарілі, зворотні погляди сумісності, як-от sysindexes
. (4) Ваш сценарій передбачає, що всі таблиці знаходяться в dbo
схемі (або, що ще гірше, схема за замовчуванням виконуваного користувача, якої може навіть не бути dbo
).
Це можна зробити, використовуючи 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
dbo
, і 2) імена ніколи не можуть містити ]
- обидва ці випадки можуть бути правдивими у випадку ОП, але все-таки це було б добре ідея згадати ці припущення, тому що застереження, які випливають з них, можуть бути не зовсім очевидні для інших людей. Однак, як я вже говорив на початку, головна проблема з цією відповіддю полягає в тому, що він просто перезапускає вже існуючу пропозицію, не додаючи жодної нової цінності.
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
PRINT
оператора. Як ваша відповідь краща за найвищу відповідь?