【问题标题】:Remove all tables from schema except specific ones in SQL?从架构中删除除 SQL 中的特定表之外的所有表?
【发布时间】:2021-10-29 03:51:12
【问题描述】:

我有一个 SQL 数据库,我想删除几乎所有与特定架构相关的表,但其中几个除外。因此,我认为我需要编辑以下 sql 查询(删除特定模式的所有表):

EXEC sp_MSforeachtable
@command1 = 'DROP TABLE ?'
, @whereand = 'AND SCHEMA_NAME(schema_id) = ''your_schema_name'' '

您能否建议一种聪明而优雅的方式,以便我可以添加我想要保留的表格列表并删除其他所有内容?

【问题讨论】:

  • 您打算多久执行一次?
  • 理论上无限次......可能是一周一次或一天几次

标签: sql sql-server schema


【解决方案1】:

如果您想继续使用sp_msforeachtable,请传入表名集以继续使用临时表。下面是一个使用 boo 架构的示例:


create schema boo;
create table boo.t(i int);

create table #keep (name sysname); 
insert #keep values ('myFirsttable'), ('mySecondTable'), ('myThirdTable');

exec sp_msforeachtable 
   @command1='drop table ?; print ''dropped ?''',
   @whereand = 'and schema_name(schema_id) = ''your_schema_name'' and object_name(object_id) not in (select name from #keep)';

但就个人而言,我可能只是用游标编写自己的存储过程。更难搞砸了。

请注意,此解决方案希望您将要保留的表放入临时表中。 Charlieface 的解决方案希望您将要删除的表的名称放入 table 变量中。

【讨论】:

  • 感谢您的回答。在我看来,我可以插入一个表的名称。如果我有不止一个怎么办?我可以这样做:插入#keep select 'mytable1', 'mytable2;
  • 只需将多行插入#keep,是的。尽管您那里的语法不起作用。而是使用...create table #keep (name sysname); insert #keep values ('mytable'), ('mySecondTable'), ('myThirdTable') --, etc
  • 我更新了你的答案,现在正确吗?
  • 是的,这就是语法。
  • 请注意,这是相当危险的,例如,如果您在将要保留的表名放入#keep 表时打错了怎么办?然后你可以放下一张你不打算放下的桌子!所以,你知道,在事务中执行此操作(我添加了一个打印语句,因此它输出所有被删除的表)
【解决方案2】:

您可以将要删除的表列表存储在表变量或表值参数@tables 中,然后您可以简单地使用它执行动态SQL。

DECLARE @tables TABLE (tablename sysname);
INSERT @tables (tablename)
SELECT t.name
FROM sys.tables t
WHERE t.schema_id = SCHEMA_ID('your_schema_name');

DECLARE @sql nvarchar(max) =
(
    SELECT STRING_AGG(CAST(
        'DROP TABLE ' + QUOTENAME('your_schema_name') + '.' + QUOTENAME(tablename) + ';'
      AS nvarchar(max)), '
'   )
    FROM @tables
);

EXEC sp_executesql @sql;

或者,直接从sys.tables中选择它

DECLARE @sql nvarchar(max) =
(
    SELECT STRING_AGG(CAST(
        'DROP TABLE ' + QUOTENAME(SCHEMA_NAME(t.schema_id)) + '.' + QUOTENAME(t.name) + ';'
      AS nvarchar(max)), '
'   )
    FROM sys.tables t
    WHERE t.schema_id = SCHEMA_ID('your_schema_name')
);

EXEC sp_executesql @sql;

【讨论】:

  • 感谢您的回答!所以只是说清楚,因为我不是那么专家。我应该在哪里放置表格列表?这里? TABLE (my_tables_name sysname) 什么是 sysname?我应该用其他东西代替它吗?
  • sysname 只是nvarchar(128) 的别名。取决于您希望如何获取表列表。您会通过参数传递它们,还是进行一些复杂的搜索?然后将它们插入@tables,如图所示。或者你可以做INSERT @tables (tablename) VALUES ('table1'),('table2');如果它只是一个简单的模式过滤器,那么你可以做第二个版本。
猜你喜欢
  • 2015-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-09
  • 2019-08-16
  • 2010-09-07
  • 1970-01-01
  • 2015-08-08
相关资源
最近更新 更多