您好我想知道是否可以删除自定义模式下创建的数据库中的所有表,例如DBO1 ...使用一个SQL查询或特殊脚本。
谢谢
答案 0 :(得分:84)
这将为您生成所有DROP TABLE语句并将SQL语句PRINT输出。 然后,您可以在复制和执行之前验证它的预期。只要确保你100%确定......可能先备份:)
DECLARE @SqlStatement NVARCHAR(MAX)
SELECT @SqlStatement =
COALESCE(@SqlStatement, N'') + N'DROP TABLE [DBO1].' + QUOTENAME(TABLE_NAME) + N';' + CHAR(13)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'DBO1' and TABLE_TYPE = 'BASE TABLE'
PRINT @SqlStatement
答案 1 :(得分:28)
我知道一些旧帖子,但我正在寻找这样的东西,并发现原始答案非常有用。也就是说,该脚本还会尝试删除该架构中可能存在的视图并给出错误消息,因为您最终会尝试通过发出DROP TABLE语句来删除视图。
我最后写这篇文章是因为我需要删除给定模式中的所有表,视图,过程和函数。也许不是最优雅的方式来实现这一点,但它对我有用,我想我会分享。
DECLARE @Sql VARCHAR(MAX)
, @Schema varchar(20)
SET @Schema = 'Integration' --put your schema name between these quotes
--tables
SELECT @Sql = COALESCE(@Sql,'') + 'DROP TABLE %SCHEMA%.' + QUOTENAME(TABLE_NAME) + ';' + CHAR(13)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = @Schema
AND TABLE_TYPE = 'BASE TABLE'
ORDER BY TABLE_NAME
--views
SELECT @Sql = COALESCE(@Sql,'') + 'DROP VIEW %SCHEMA%.' + QUOTENAME(TABLE_NAME) + ';' + CHAR(13)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = @Schema
AND TABLE_TYPE = 'VIEW'
ORDER BY TABLE_NAME
--Procedures
SELECT @Sql = COALESCE(@Sql,'') + 'DROP PROCEDURE %SCHEMA%.' + QUOTENAME(ROUTINE_NAME) + ';' + CHAR(13)
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_SCHEMA = @Schema
AND ROUTINE_TYPE = 'PROCEDURE'
ORDER BY ROUTINE_NAME
--Functions
SELECT @Sql = COALESCE(@Sql,'') + 'DROP FUNCTION %SCHEMA%.' + QUOTENAME(ROUTINE_NAME) + ';' + CHAR(13)
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_SCHEMA = @Schema
AND ROUTINE_TYPE = 'FUNCTION'
ORDER BY ROUTINE_NAME
SELECT @Sql = COALESCE(REPLACE(@Sql,'%SCHEMA%',@Schema), '')
PRINT @Sql
答案 2 :(得分:14)
基于@Kevo的回答,我在删除表之前添加了以下内容以删除所有外键约束。我只测试过SQL2008 R2
select @Sql = COALESCE(@Sql,'') + 'ALTER TABLE %SCHEMA%.' + t.name + ' drop constraint ' +
OBJECT_NAME(d.constraint_object_id) + ';' + CHAR(13)
from sys.tables t
join sys.foreign_key_columns d on d.parent_object_id = t.object_id
inner join sys.schemas s on t.schema_id = s.schema_id
where s.name = @Schema
ORDER BY t.name;
答案 3 :(得分:13)
在其他答案的基础上,这是一个存储过程spDropSchema
,它删除模式中的所有对象和模式本身。
请注意,该过程也会尝试删除序列对象,因此它只能在SQL Server 2012及更高版本上运行。
IF EXISTS (SELECT * FROM sysobjects WHERE type = 'P' AND name = 'spDropSchema')
BEGIN
DROP PROCEDURE spDropSchema
END
GO
CREATE PROCEDURE spDropSchema(@Schema nvarchar(200))
AS
DECLARE @Sql NVARCHAR(MAX) = '';
--constraints
SELECT @Sql = @Sql + 'ALTER TABLE '+ QUOTENAME(@Schema) + '.' + QUOTENAME(t.name) + ' DROP CONSTRAINT ' + QUOTENAME(f.name) + ';' + CHAR(13)
FROM sys.tables t
inner join sys.foreign_keys f on f.parent_object_id = t.object_id
inner join sys.schemas s on t.schema_id = s.schema_id
WHERE s.name = @Schema
ORDER BY t.name;
--tables
SELECT @Sql = @Sql + 'DROP TABLE '+ QUOTENAME(@Schema) +'.' + QUOTENAME(TABLE_NAME) + ';' + CHAR(13)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = @Schema AND TABLE_TYPE = 'BASE TABLE'
ORDER BY TABLE_NAME
--views
SELECT @Sql = @Sql + 'DROP VIEW '+ QUOTENAME(@Schema) +'.' + QUOTENAME(TABLE_NAME) + ';' + CHAR(13)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = @Schema AND TABLE_TYPE = 'VIEW'
ORDER BY TABLE_NAME
--procedures
SELECT @Sql = @Sql + 'DROP PROCEDURE '+ QUOTENAME(@Schema) +'.' + QUOTENAME(ROUTINE_NAME) + ';' + CHAR(13)
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_SCHEMA = @Schema AND ROUTINE_TYPE = 'PROCEDURE'
ORDER BY ROUTINE_NAME
--functions
SELECT @Sql = @Sql + 'DROP FUNCTION '+ QUOTENAME(@Schema) +'.' + QUOTENAME(ROUTINE_NAME) + ';' + CHAR(13)
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_SCHEMA = @Schema AND ROUTINE_TYPE = 'FUNCTION'
ORDER BY ROUTINE_NAME
--sequences
SELECT @Sql = @Sql + 'DROP SEQUENCE '+ QUOTENAME(@Schema) +'.' + QUOTENAME(SEQUENCE_NAME) + ';' + CHAR(13)
FROM INFORMATION_SCHEMA.SEQUENCES
WHERE SEQUENCE_SCHEMA = @Schema
ORDER BY SEQUENCE_NAME
SELECT @Sql = @Sql + 'DROP SCHEMA '+ QUOTENAME(@Schema) + ';' + CHAR(13)
EXECUTE sp_executesql @Sql
GO
答案 4 :(得分:8)
我知道这是一个旧线程,但我认为最简单的方法是使用未记录的sp_MSforeachtable
存储过程:
EXEC sp_MSforeachtable
@command1 = 'DROP TABLE ?'
, @whereand = 'AND SCHEMA_NAME(schema_id) = ''your_schema_name'' '
可以找到关于此存储过程的详细报告here,但如果链接已经死亡,则重点是:
sp_MSforeachtable是一个存储过程,主要用于将T-SQL命令迭代地应用于当前数据库中存在的每个表。
[...]
意识到问号(?)它被用作表的替换,并且在执行期间它将被适当的表名替换。@ command1,@ command2,@ command3
sp_MSforeachtable存储过程至少需要执行一个命令(@ command1),但它最多允许执行3个命令。请注意,它将首先执行@ command1,然后执行@ command2和@ command3,最后执行每个表。<强> @precommand 强>
使用此参数提供要在@ command1之前执行的命令。设置变量环境或执行任何类型的初始化都很有用。<强> @postcommand 强>
使用此参数提供在成功执行所有命令后要执行的命令。它对控制和清理过程很有用。<强> @replacechar 强>
默认情况下,表由问号(?)字符表示。此参数允许您更改此字符。<强> @whereand 强>
默认情况下,sp_MSforeachtable应用于数据库中的所有用户表。使用此参数筛选要使用的表。在下一节中,我将解释如何过滤表格。
答案 5 :(得分:7)
同样基于@Kevo的回答,我添加了以下while循环,以解决我在TSQL Print语句中遇到的问题。消息字符串最长可达8,000个字符。如果大于8,000,则print语句将截断任何剩余字符。
DECLARE @SqlLength int
, @SqlPosition int = 1
, @printMaxLength int = 8000
SET @SqlLength = LEN(@Sql)
WHILE (@SqlLength) > @printMaxLength
BEGIN
PRINT SUBSTRING(@Sql, @SqlPosition, @printMaxLength)
SET @SqlLength = @SqlLength - @printMaxLength
SET @SqlPosition = @SqlPosition + @printMaxLength
END
IF (@SqlLength) < @printMaxLength AND (@SqlLength) > 0
BEGIN
PRINT SUBSTRING(@Sql, @SqlPosition, @printMaxLength)
END
答案 6 :(得分:3)
我将@ raider33和@Kevo的答案合并为一个直接执行的解决方案。
DECLARE @SqlStatement NVARCHAR(MAX)
DECLARE @schema varchar(30) = 'SCHEMA_NAME';
select @SqlStatement = COALESCE(@SqlStatement,'') + 'ALTER TABLE '+@schema+'.' + t.name + ' drop constraint ' +
OBJECT_NAME(d.constraint_object_id) + ';' + CHAR(13) + CHAR(10)
from sys.tables t
join sys.foreign_key_columns d on d.parent_object_id = t.object_id
inner join sys.schemas s on t.schema_id = s.schema_id
where s.name = @schema
ORDER BY t.name;
SELECT @SqlStatement +=
COALESCE(@SqlStatement, '') + 'DROP TABLE ' + @schema +'.'+ QUOTENAME(TABLE_NAME) + ';' + CHAR(13) + CHAR(10)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = @schema
EXECUTE sp_executesql @SqlStatement
答案 7 :(得分:1)
在chris LB's answer的基础上,我添加了
GROUP BY d.constraint_object_id, t.name
因为我在查询中看到了重复的约束删除。 constraint_object_id
是FK约束ID,如https://msdn.microsoft.com/en-us/library/ms186306.aspx
DECLARE @SqlStatement NVARCHAR(MAX),
@Schema NVARCHAR(20)
SET @Schema = 'aa'
SELECT @SqlStatement =
COALESCE(@SqlStatement,'') + 'ALTER TABLE '+@Schema+'.' + t.name + ' DROP CONSTRAINT ' +
OBJECT_NAME(d.constraint_object_id) + ';' + CHAR(13) + CHAR(10)
FROM sys.tables t
JOIN sys.foreign_key_columns d on t.object_id = d.parent_object_id
INNER JOIN sys.schemas s on t.schema_id = s.schema_id
WHERE s.name = @Schema
GROUP BY d.constraint_object_id, t.name
ORDER BY t.name;
答案 8 :(得分:1)
为了防止有人,我将其作为存储过程添加到master数据库,以便在任何db / schema上方便地使用它。
可以像这样调用:
EXEC master.dbo.dropTablesInSchema 'my_db', 'dbo
存储过程创建脚本:
CREATE PROC [master].[dbo].[dropTablesInSchema]
@db nvarchar(max),
@schema nvarchar(max)
AS
BEGIN
DECLARE @Tables TABLE (name nvarchar(max))
INSERT INTO @Tables
EXEC ('SELECT TABLE_NAME FROM [' + @db + '].INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ''' + @schema + ''' and TABLE_TYPE =''BASE TABLE''')
DECLARE @SqlStatement NVARCHAR(MAX)
SELECT @SqlStatement =
COALESCE(@SqlStatement, N'') + N'DROP TABLE [' + @db + '].[' + @schema + '].' + QUOTENAME(NAME) + N';' + CHAR(13)
FROM @Tables
EXEC(@SqlStatement)
END
答案 9 :(得分:0)
这将生成所有带检查的DROP TABLE和DROP VIEW。
DECLARE @SqlStatement NVARCHAR(MAX)
SELECT @SqlStatement =
COALESCE(@SqlStatement, N'') + N'IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'''+'['+TABLE_SCHEMA+'].' + QUOTENAME(TABLE_NAME) +''' )' + CHAR(13)+
' DROP '+ TABLE_TYPE +' ['+TABLE_SCHEMA+'].' + QUOTENAME(TABLE_NAME) + N';' + CHAR(13)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA in ('SCHEMA1','SCHEMA2','SCHEMA13' )
ORDER BY TABLE_SCHEMA
PRINT REPLACE(@SqlStatement,'DROP BASE TABLE ','DROP TABLE ')
GO
答案 10 :(得分:0)
select 'DROP TABLE [TABSCHEMA].' + QUOTENAME(TABLE_NAME) + N';' from INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'TABSCHEMA' and TABLE_TYPE = 'BASE TABLE'
答案 11 :(得分:0)
删除模式中的所有表,可以修改它以返回表的任何子集。
declare @schema varchar(10) = 'temp'
declare @max_number_of_tables int = 1000
declare @sql nvarchar(max)
declare @index int = 0
while (
select count(*)
from
sys.objects obj
join sys.schemas s
on (s.schema_id=obj.schema_id)
where
s.name= @schema
and obj.type = 'U'
AND obj.is_ms_shipped = 0x0) > 0 and @index < @max_number_of_tables
begin
set @index = @index+1
select top 1
@sql = N'DROP TABLE [' + @schema + '].[' + obj.name + ']'
from
sys.objects obj
join sys.schemas s
on (s.schema_id=obj.schema_id)
where
s.name = @schema
and obj.type = 'U'
AND obj.is_ms_shipped = 0x0
order by obj.name
print @sql
execute(@sql)
end
答案 12 :(得分:0)
接受的答案的修改仅适用于复制粘贴。
将db
更改为数据库,并将@dbSchema
设置为架构。
USE db -- CHANGE TO YOUR DB
GO
DECLARE @dbSchema NVARCHAR(200);
SET @dbSchema = 'dbo' -- CHANGE TO YOUR SCHEMA
DECLARE @SqlStatement NVARCHAR(MAX)
SELECT @SqlStatement =
COALESCE(@SqlStatement, N'') + N'DROP TABLE ' +'[' + @dbSchema +']' + '.' + QUOTENAME(TABLE_NAME) + N';' + CHAR(13)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = @dbSchema and TABLE_TYPE = 'BASE TABLE'
EXEC sp_executesql @SqlStatement