删除没有表的数据库

时间:2014-07-26 01:52:43

标签: sql sql-server sql-server-2005

是否有查询删除/删除没有表格的数据库(删除空数据库)?

服务器是Microsoft SQL Server 2005

3 个答案:

答案 0 :(得分:1)

这应该这样做。 在实验室机器上测试,它删除了所有具有0个用户表的数据库。 但请注意,表格不一定是数据库中唯一的东西。可能存在某人可能仍需要的存储过程,功能等。

请注意,这是一项非常危险的操作,因为它会导致数据丢失。自行承担使用风险。我对您造成的损失不承担任何责任。

USE [master];
DECLARE @name varchar(50);
DECLARE @innerQuery varchar(max);
DECLARE tableCursor CURSOR FOR SELECT name FROM sys.databases where owner_sid != 0x01;
OPEN tableCursor;

FETCH NEXT FROM tableCursor
INTO @name

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @innerQuery = 'USE [' + @name + ']; IF (SELECT COUNT(*) FROM sys.objects WHERE type = ''U'') = 0
    BEGIN
        USE [master];
        DROP DATABASE [' + @name + ']
    END'
    EXEC(@innerQuery)
    FETCH NEXT FROM tableCursor INTO @name
END

CLOSE tableCursor;
DEALLOCATE tableCursor;

另请注意,如果正在使用数据库,SQL Server将拒绝删除它。因此,如果尝试删除特定数据库的其他连接,则该命令将中止。

为避免此问题,您可以将有问题的数据库设置为单用户模式。

以下脚本与上述脚本相同,不同之处在于它还将目标数据库设置为单用户模式以终止活动连接。 请特别注意这一点,因为它本质上是核选项:

use [master];
DECLARE @name varchar(50);
DECLARE @innerQuery varchar(max);
DECLARE tableCursor CURSOR FOR SELECT name FROM sys.databases where owner_sid != 0x01;
OPEN tableCursor;

FETCH NEXT FROM tableCursor
INTO @name

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @innerQuery = 
    'USE [' + @name + '];
    IF (SELECT COUNT(*) FROM sys.objects WHERE type = ''U'') = 0
    BEGIN
        USE [master];
        ALTER DATABASE [' + @name + '] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
        DROP DATABASE [' + @name + '];
    END'
    EXEC(@innerQuery)
    FETCH NEXT FROM tableCursor INTO @name
END

CLOSE tableCursor;
DEALLOCATE tableCursor;

答案 1 :(得分:0)

我认为这是不可能的(至少不使用TSQL命令,可能是某处的存储过程)。您必须查询sysobjects并在发现任何内容时中止。 (并且你必须决定是否要忽略一些系统对象,比如设计表)。

答案 2 :(得分:0)

下面的脚本将生成所需的DROP DATABASE脚本。您可以调整它来执行该语句(在主数据库上下文中)但我建议您先查看它以防万一。

EXEC sp_MSforeachdb N'
    USE [?];
    IF N''?'' NOT IN(N''master'', N''model'', N''msdb'', N''tempdb'')
    BEGIN
        IF NOT EXISTS(
            SELECT *
            FROM sys.tables
            WHERE
                OBJECTPROPERTYEX(object_id, ''IsMSShipped'') = 0
            )
        BEGIN
            PRINT ''DROP DATABASE [?];'';
        END;
    END;';