删除包含所有依赖项的表(Microsoft SQL Server)

时间:2011-04-22 18:35:06

标签: sql sql-server tsql

如何在不事先了解其依赖关系的情况下删除包含所有依赖项[SP,视图等](Microsoft SQL Server)的表?我知道我可以在Mangement Studio中显示所有依赖项,但我正在搜索实用程序脚本,我可以简单地指定一个对象,它将删除该对象及其所有依赖项。

5 个答案:

答案 0 :(得分:25)

最好的办法是“为Drop生成脚本”

选择数据库 - >右键单击 - >任务 - >生成脚本 - 将打开生成脚本的向导

  • 选择数据库 - >下
  • 将选项'要创建的脚本'设置为true(想要创建)
  • 将选项'要删除的脚本'设置为true(想要删除)
  • 将选项'为依赖对象生成脚本'设置为true - >下一步
  • 选中复选框以选择要创建脚本的对象
  • 选择编写脚本的选项(文件,新窗口,剪贴板)

执行脚本

通过这种方式,我们可以自定义脚本,即我们可以为数据库的选定对象编写脚本。

我希望这会对你有所帮助!

祝福,JP

答案 1 :(得分:2)

您可以使用Sp_Depends查找依赖项。有了这个你可以修改the script from this answer也许不那么懒的人会为你做这件事。

注意:每个对象当然都有自己的依赖关系,所以你也需要处理它们。

答案 2 :(得分:1)

使用其架构限定名称删除SQL对象。对于表,首先删除约束。 错误被忽略。

create procedure [dbo].[spDropObject] (@fullname nvarchar(520))
as
begin
    begin try
        declare @type nvarchar(5)
        declare @resolvedFullname nvarchar(520) 
        declare @resolvedName nvarchar(255) 
        set @type = null
        set @resolvedFullname = null
        set @resolvedName = null

        --find the object
        select 
        @type = o.[type] 
        ,@resolvedFullname = '[' + object_schema_name(o.id) +  '].[' + o.[name] + ']'
        ,@resolvedName = '[' + o.[name] + ']'
        from dbo.sysobjects o
        where id = object_id(@fullname)

        --PROCEDURE
        if(@type = 'P') 
        begin
            exec('drop procedure ' + @resolvedFullname);
            return;
        end

        --VIEW
        if(@type = 'V') 
        begin
            exec('drop view ' + @resolvedFullname);
            return;
        end

        --FUNCTION
        if(@type = 'FN' or @type = 'TF') 
        begin
            exec('drop function ' + @resolvedFullname);
            return;
        end

        --TRIGGER
        if(@type = 'TF') 
        begin
            exec('drop trigger ' + @resolvedFullname);
            return;
        end

        --CONSTRAINT
        if(@type = 'C' or @type = 'UQ' or @type = 'D' or @type = 'F' or @type = 'PK' or @type = 'K') 
        begin
            declare @fullTablename nvarchar(520);
            set @fullTablename = null

            --find the contraint's table
            select @fullTablename ='[' + object_schema_name(t.[object_id]) + '].[' + t.[Name] + ']'
            from sys.tables t
            join sys.schemas s on t.schema_id = s.schema_id
            where t.object_id = (select parent_obj from dbo.sysobjects where id = object_id(@resolvedFullname))

            exec('alter table ' + @fullTablename + ' drop constraint ' + @resolvedName);
            return; 
        end

        --TABLE (drop all constraints then drop the table)
        if(@type = 'U') 
        begin
            --find FK references to the table
            declare @fktab table([Name] nvarchar(255))
            insert @fktab 
            select 
            [Name] = '[' + object_name(fkc.[constraint_object_id]) + ']'
            /*
            ,[Parent] = '[' + object_schema_name(fkc.[parent_object_id]) +  '].[' + object_name(fkc.[parent_object_id]) + ']'
            ,[Ref] = '[' + object_schema_name(fkc.[referenced_object_id]) +  '].[' + object_name(fkc.[referenced_object_id]) + ']'
            */
            from sys.foreign_key_columns as fkc
            where referenced_object_id = object_id(@resolvedFullname)
            order by [Name]

            --iterate FKs
            while(1=1)
            begin
                declare @constraint nvarchar(255)
                set @constraint = null
                select top 1
                @constraint = [Name]
                from @fktab

                if(@constraint is not null)
                begin
                    --drop FK constraint
                    exec [dbo].[spDropObject] @constraint;
                    delete from @fktab where [Name] = @constraint --remove current record from working table
                end
                else break;
            end         

            --find constraints for table
            declare @constraintTab table ([Name] nvarchar(255));

            insert @constraintTab
            select [name] 
            from sys.objects 
            where parent_object_id = object_id(@resolvedFullname)
            order by [name]

            --iterate constraints
            while(1=1)
            begin
                set @constraint = null;
                select top 1 @constraint = [Name] from @constraintTab

                if(@constraint is not null)
                begin
                    --drop constraint
                    exec [dbo].[spDropObject] @constraint;
                    delete from @constraintTab where [Name] = @constraint --remove current record from working table
                end
                else break;
            end

            --drop table
            exec('drop table ' + @resolvedFullname);
            return;
        end
    end try
    begin catch
        declare @message nvarchar(max)
        set @message = error_message( ) ;
        print @message
    end catch
end

答案 3 :(得分:0)

就我而言,我特别想删除指定的表和依赖于该表的表。对我来说,只删除引用它的外键约束对我没有用。我写了一个存储过程来做到这一点

CREATE PROCEDURE DropDependentTables (
  @tableName NVARCHAR(64))
AS
-- Find and drop all tables that depend on @tableName
WHILE EXISTS(SELECT *
  FROM sys.foreign_keys
  WHERE OBJECT_NAME(referenced_object_id) = @tableName AND
    OBJECT_NAME(parent_object_id) != @tableName)
BEGIN
  DECLARE @dependentTableName NVARCHAR(64)
  SELECT TOP 1 @dependentTableName = OBJECT_NAME(parent_object_id)
    FROM sys.foreign_keys
    WHERE OBJECT_NAME(referenced_object_id) = @tableName AND
      OBJECT_NAME(parent_object_id) != @tableName

    EXEC DropDependentTables @dependentTableName
END

答案 4 :(得分:0)

我要留下一个较晚的答案(大约10年后)。希望您会觉得方便。

在我们公司中,我们使用此脚本正确删除数据库表。对于每个表,我们首先删除依赖项(REFERENTIAL_CONSTRAINTS),然后删除表本身。

USE [database-name]

DECLARE @Sql NVARCHAR(500) DECLARE @Cursor CURSOR

SET @Cursor = CURSOR FAST_FORWARD FOR
SELECT DISTINCT sql = 'ALTER TABLE [' + tc2.TABLE_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
Exec sp_executesql @Sql
FETCH NEXT FROM @Cursor INTO @Sql
END

CLOSE @Cursor DEALLOCATE @Cursor
GO

EXEC sp_MSforeachtable 'DROP TABLE ?'
GO

这笔钱归功于我的一位同事Abolfazl Najafzade来编写脚本。