【发布时间】:2012-01-19 21:59:31
【问题描述】:
您好,我想知道是否可以删除数据库中在自定义架构下创建的所有表,例如 DBO1...使用一个 sql 查询或特殊脚本。
谢谢
【问题讨论】:
标签: sql sql-server
您好,我想知道是否可以删除数据库中在自定义架构下创建的所有表,例如 DBO1...使用一个 sql 查询或特殊脚本。
谢谢
【问题讨论】:
标签: sql sql-server
这将为您生成所有 DROP TABLE 语句并将 SQL 语句打印出来。 然后,您可以在复制和执行之前验证它是否符合您的期望。只要确保你 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
【讨论】:
TABLE_TYPE = 'BASE TABLE'进行过滤
我知道有些旧线程,但我一直在寻找类似的东西,发现原始答案非常有帮助。也就是说,该脚本还将尝试删除该架构中可能存在的视图并给您一条错误消息,因为您最终会尝试通过发出 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
【讨论】:
我知道这是一个旧线程,但我认为最简单的方法是使用未记录的 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 应用于数据库中的所有用户表。使用此参数过滤您要使用的表。在下一节中,我将解释如何过滤表格。
【讨论】:
同样基于@Kevo 的回答,我添加了以下 while 循环来解决我在使用 TSQL Print 语句时遇到的问题。消息字符串最长可达 8,000 个字符。如果大于 8,000,打印语句将截断任何剩余的字符。
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
【讨论】:
select 'DROP TABLE [TABSCHEMA].' + QUOTENAME(TABLE_NAME) + N';' from INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'TABSCHEMA' and TABLE_TYPE = 'BASE TABLE'
【讨论】:
在其他答案的基础上,这是一个存储过程 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
--types
SELECT @Sql = @Sql + 'DROP TYPE ' + QUOTENAME(@Schema) + '.' + QUOTENAME(t.name) + ';' + CHAR(13)
FROM sys.types t
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE t.is_user_defined = 1 AND
s.name = @Schema
ORDER BY s.name
SELECT @Sql = @Sql + 'DROP SCHEMA '+ QUOTENAME(@Schema) + ';' + CHAR(13)
EXECUTE sp_executesql @Sql
GO
【讨论】:
SELECT * FROM sys.types where is_user_defined = 1 找到它们
以防万一它对某人有所帮助,我将其作为存储过程添加到主数据库中,以便在任何数据库/架构上方便地使用它。
可以这样调用:
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
【讨论】:
我将@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
【讨论】:
在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;
【讨论】:
基于@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;
【讨论】:
这将生成所有 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
【讨论】:
删除 schema 中的所有表,可以修改为返回表的任何子集。
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
【讨论】:
修改已接受的答案,只需复制粘贴即可。
将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
【讨论】: