sql-server - 在 SQL Server 2005 中,我可以在不设置表属性的情况下执行级联删除吗?

标签 sql-server sql-server-2005 cascade

我有一个充满客户数据的数据库。它太大了,操作起来确实很麻烦,我宁愿把它缩小到 10% 的客户,这对于开发来说已经足够了。我有很多表,我不想用“ON DELETE CASCADE”来更改它们,特别是因为这是一次性交易。

我可以在不先设置表的情况下执行级联所有表的删除操作吗?如果没有,我最好的选择是什么?

最佳答案

结合您的建议和我在网上找到的脚本,我制作了一个过程,该过程将生成 SQL,您可以运行该 SQL 来执行级联删除,而不管ON DELETE CASCADE如何。这可能是浪费时间,但我写得很开心。这样做的一个优点是,您可以在每一行之间放置一个 GO 语句,并且它不必是一个大事务。最初是一个递归过程;这个将递归展开到堆栈表中。

create procedure usp_delete_cascade (
    @base_table_name varchar(200), @base_criteria nvarchar(1000)
)
as begin
    -- Adapted from http://www.sqlteam.com/article/performing-a-cascade-delete-in-sql-server-7
    -- Expects the name of a table, and a conditional for selecting rows
    -- within that table that you want deleted.
    -- Produces SQL that, when run, deletes all table rows referencing the ones
    -- you initially selected, cascading into any number of tables,
    -- without the need for "ON DELETE CASCADE".
    -- Does not appear to work with self-referencing tables, but it will
    -- delete everything beneath them.
    -- To make it easy on the server, put a "GO" statement between each line.

    declare @to_delete table (
        id int identity(1, 1) primary key not null,
        criteria nvarchar(1000) not null,
        table_name varchar(200) not null,
        processed bit not null,
        delete_sql varchar(1000)
    )

    insert into @to_delete (criteria, table_name, processed) values (@base_criteria, @base_table_name, 0)

    declare @id int, @criteria nvarchar(1000), @table_name varchar(200)
    while exists(select 1 from @to_delete where processed = 0) begin
        select top 1 @id = id, @criteria = criteria, @table_name = table_name from @to_delete where processed = 0 order by id desc

        insert into @to_delete (criteria, table_name, processed)
            select referencing_column.name + ' in (select [' + referenced_column.name + '] from [' + @table_name +'] where ' + @criteria + ')',
                referencing_table.name,
                0
            from  sys.foreign_key_columns fk
                inner join sys.columns referencing_column on fk.parent_object_id = referencing_column.object_id 
                    and fk.parent_column_id = referencing_column.column_id 
                inner join  sys.columns referenced_column on fk.referenced_object_id = referenced_column.object_id 
                    and fk.referenced_column_id = referenced_column.column_id 
                inner join  sys.objects referencing_table on fk.parent_object_id = referencing_table.object_id 
                inner join  sys.objects referenced_table on fk.referenced_object_id = referenced_table.object_id 
                inner join  sys.objects constraint_object on fk.constraint_object_id = constraint_object.object_id
            where referenced_table.name = @table_name
                and referencing_table.name != referenced_table.name

        update @to_delete set
            processed = 1
        where id = @id
    end

    select 'print ''deleting from ' + table_name + '...''; delete from [' + table_name + '] where ' + criteria from @to_delete order by id desc
end

exec usp_delete_cascade 'root_table_name', 'id = 123'

关于sql-server - 在 SQL Server 2005 中,我可以在不设置表属性的情况下执行级联删除吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/116968/

相关文章:

.net - 如何说服sql server 2008r2使用clr v4.0而不是v2.0?

sql-server - SQL Server 同步备选方案

sql-server - Cloud Composer 无法连接到 Azure VM 中安装的 SQL Server 数据库

sql - sys.columns.max_length 的替代方案

database - 如何连接来自两个不同数据库的两个表?

sql-server - 如何将序列号连接到不相关的数据 (SQL Server)

java - Hibernate 尝试在 saveOrUpdate 方法中删除不存在表中的行

sql - oracle中外键同表时如何添加级联删除

postgresql - 级联触发器不起作用

mysql - 如何编写员工表和部门表的 SQL 查询