在SQl Server 2005中,我是否可以通过删除所有的表和存储过程、触发器、约束以及SQl语句中的所有依赖项来清理数据库?

要求理由:

我想有一个DB脚本清理现有的DB,这不是在使用,而不是创建新的,特别是当你必须把一个请求到你的DB管理员,并等待一段时间才能完成!


当前回答

在我看来这是一个相当危险的功能。如果你要实现这样的东西,我会确保以一种你不能每次事故都运行它的方式正确地保护它。

如前所述,您可以自己创建某种存储过程。 在SQL Server 2005中,您可以查看这个系统表来确定和查找您想要删除的对象。

select * from sys.objects

其他回答

为了补充Ivan的回答,我还需要删除所有用户定义的类型,所以我在脚本中添加了以下内容:

/* Drop all user-defined types */
DECLARE @name VARCHAR(128)
DECLARE @SQL VARCHAR(254)

SELECT @name = (select TOP 1 [name] from sys.types where is_user_defined = 1)

WHILE @name IS NOT NULL
BEGIN
    SELECT @SQL = 'DROP TYPE [dbo].[' + RTRIM(@name) +']'
    EXEC (@SQL)
    PRINT 'Dropped Type: ' + @name
    SELECT @name = (select TOP 1 [name] from sys.types where is_user_defined = 1)
END
GO

您必须首先禁用所有触发器和约束。

EXEC sp_MSforeachtable @command1="ALTER TABLE ? NOCHECK CONSTRAINT ALL"

EXEC sp_MSforeachtable @command1="ALTER TABLE ? DISABLE TRIGGER ALL"

在此之后,您可以生成用于删除对象的脚本

SELECT 'Drop Table '+name FROM sys.tables WHERE type='U';

SELECT 'Drop Procedure '+name FROM  sys.procedures WHERE type='P';

执行生成的语句。

我今晚不小心在我的主数据库上运行了一个db初始化脚本。不管怎样,我很快就碰到了这个话题。我使用:exec sp_MSforeachtable 'DROP TABLE ?'回答,但必须多次执行它,直到它没有错误(依赖)。在此之后,我偶然发现了一些其他线程,并将其拼凑在一起以删除所有存储过程和函数。

DECLARE mycur CURSOR FOR select O.type_desc,schema_id,O.name
from 
    sys.objects             O LEFT OUTER JOIN
    sys.extended_properties E ON O.object_id = E.major_id
WHERE
    O.name IS NOT NULL
    AND ISNULL(O.is_ms_shipped, 0) = 0
    AND ISNULL(E.name, '') <> 'microsoft_database_tools_support'
    AND ( O.type_desc = 'SQL_STORED_PROCEDURE' OR O.type_desc = 'SQL_SCALAR_FUNCTION' )
ORDER BY O.type_desc,O.name;

OPEN mycur;

DECLARE @schema_id int;
DECLARE @fname varchar(256);
DECLARE @sname varchar(256);
DECLARE @ftype varchar(256);

FETCH NEXT FROM mycur INTO @ftype, @schema_id, @fname;

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @sname = SCHEMA_NAME( @schema_id );
    IF @ftype = 'SQL_STORED_PROCEDURE'
        EXEC( 'DROP PROCEDURE "' + @sname + '"."' + @fname + '"' );
    IF @ftype = 'SQL_SCALAR_FUNCTION'
        EXEC( 'DROP FUNCTION "' + @sname + '"."' + @fname + '"' );

    FETCH NEXT FROM mycur INTO @ftype, @schema_id, @fname;
END

CLOSE mycur
DEALLOCATE mycur

GO

我在这里尝试了一些脚本,但它们不适合我,因为我的表是模式中的。所以我整理了以下内容。注意,这个脚本接受一个模式列表,然后按顺序删除。您需要确保您的模式有一个完整的顺序。如果存在任何循环依赖关系,那么它将失败。

PRINT 'Dropping whole database'
GO

------------------------------------------
-- Drop constraints
------------------------------------------
DECLARE @Sql NVARCHAR(500) DECLARE @Cursor CURSOR

SET @Cursor = CURSOR FAST_FORWARD FOR
SELECT DISTINCT sql = 'ALTER TABLE ['+tc2.CONSTRAINT_SCHEMA+'].[' + tc2.TABLE_NAME + '] DROP [' + rc1.CONSTRAINT_NAME + ']'
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc1
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc2 ON tc2.CONSTRAINT_NAME =rc1.CONSTRAINT_NAME

OPEN @Cursor FETCH NEXT FROM @Cursor INTO @Sql

WHILE (@@FETCH_STATUS = 0)
BEGIN
PRINT @Sql
Exec (@Sql)
FETCH NEXT FROM @Cursor INTO @Sql
END

CLOSE @Cursor DEALLOCATE @Cursor
GO


------------------------------------------
-- Drop views
------------------------------------------

DECLARE @sql VARCHAR(MAX) = ''
        , @crlf VARCHAR(2) = CHAR(13) + CHAR(10) ;

SELECT @sql = @sql + 'DROP VIEW ' + QUOTENAME(SCHEMA_NAME(schema_id)) + '.' + QUOTENAME(v.name) +';' + @crlf
FROM   sys.views v

PRINT @sql;
EXEC(@sql);
GO
------------------------------------------
-- Drop procs
------------------------------------------
PRINT 'Dropping all procs ...'
GO

DECLARE @sql VARCHAR(MAX) = ''
        , @crlf VARCHAR(2) = CHAR(13) + CHAR(10) ;

SELECT @sql = @sql + 'DROP PROC ' + QUOTENAME(SCHEMA_NAME(p.schema_id)) + '.' + QUOTENAME(p.name) +';' + @crlf
FROM   [sys].[procedures] p

PRINT @sql;
EXEC(@sql);
GO

------------------------------------------
-- Drop tables
------------------------------------------
PRINT 'Dropping all tables ...'
GO
EXEC sp_MSForEachTable 'DROP TABLE ?'
GO

------------------------------------------
-- Drop sequences
------------------------------------------

PRINT 'Dropping all sequences ...'
GO
DECLARE @DropSeqSql varchar(1024)
DECLARE DropSeqCursor CURSOR FOR
SELECT DISTINCT 'DROP SEQUENCE ' + s.SEQUENCE_SCHEMA + '.' + s.SEQUENCE_NAME
    FROM INFORMATION_SCHEMA.SEQUENCES s

OPEN DropSeqCursor

FETCH NEXT FROM DropSeqCursor INTO @DropSeqSql

WHILE ( @@FETCH_STATUS <> -1 )
BEGIN
    PRINT @DropSeqSql
    EXECUTE( @DropSeqSql )
    FETCH NEXT FROM DropSeqCursor INTO @DropSeqSql
END

CLOSE DropSeqCursor
DEALLOCATE DropSeqCursor
GO

------------------------------------------
-- Drop Schemas
------------------------------------------


DECLARE @schemas as varchar(1000) = 'StaticData,Ird,DataImport,Collateral,Report,Cds,CommonTrade,MarketData,TypeCode'
DECLARE @schemasXml as xml = cast(('<schema>'+replace(@schemas,',' ,'</schema><schema>')+'</schema>') as xml)

DECLARE @Sql NVARCHAR(500) DECLARE @Cursor CURSOR

SET @Cursor = CURSOR FAST_FORWARD FOR
SELECT sql = 'DROP SCHEMA ['+schemaName+']' FROM 
(SELECT CAST(T.schemaName.query('text()') as VARCHAR(200)) as schemaName FROM @schemasXml.nodes('/schema') T(schemaName)) as X
JOIN information_schema.schemata S on S.schema_name = X.schemaName

OPEN @Cursor FETCH NEXT FROM @Cursor INTO @Sql

WHILE (@@FETCH_STATUS = 0)
BEGIN
PRINT @Sql
Exec (@Sql)
FETCH NEXT FROM @Cursor INTO @Sql
END

CLOSE @Cursor DEALLOCATE @Cursor
GO

我会在两个语句中做到:DROP DATABASE ??

然后创建数据库??