2008-09-22 31 views
32

我有一個數據庫充滿了客戶數據。它太大了,操作起來真的很麻煩,我寧願把它減少到10%的客戶,這對發展來說是很大的。我有很多表,我不想用「ON DELETE CASCADE」來改變它們,特別是因爲這是一次性交易。在SQL Server 2005中,我可以在沒有設置表格屬性的情況下進行級聯刪除嗎?

我可以做一個刪除操作,級聯所有我的表而不先設置它們嗎?如果不是,我最好的選擇是什麼?

回答

52

結合您的建議和腳本我在網上找到,我做了會產生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' 
+0

好腳本!謝謝! – splattne 2009-06-15 09:17:32

+0

這個腳本允許我發送例如'code = ABC和name = dave' – ThePower 2011-04-28 08:32:55

2

我通常只是手寫查詢來刪除我不想要的記錄,並將其保存爲.sql文件以供將來參考。僞代碼:從主表,我想刪除到一個臨時表

  • 寫出每個相關表,加入到臨時表中刪除查詢記錄

    1. 選擇ID的。
    2. 爲連接到我的臨時表的主表寫入刪除查詢。
  • 2

    我的建議是繼續編寫一個腳本,該腳本會將刪除層疊添加到數據庫中的每個關係,同時導出修改關係的列表。然後,您可以反轉該過程並刪除列表中每個表上的on delete cascade命令。

    2

    就個人而言,如果你要離開生產記錄,我也會留下他們的發展。否則,你可能會編寫在記錄集很小時工作正常但在遇到真實記錄集時超時的代碼。

    但是,如果您決定這樣做,我會首先將要從主表中刪除的記錄的id字段複製到工作表中。然後,我將把每個相關表格寫入一個刪除連接到該工作表,以僅刪除這些記錄。用父表完成。確保將這些內容寫入腳本並在下次希望與測試數據做類似的事情時進行保存,您可以輕鬆運行它,而無需弄清楚需要從中刪除記錄的重複表是什麼。

    5

    進入SQL Server Management Studio並右鍵單擊該數據庫。選擇任務 - >生成腳本。點擊下一步兩次。在「選項」窗口中,選擇將其設置爲僅生成CREATE語句,並將所有內容都設置爲除外部鍵之外的False。點擊下一步。選擇表格並再次單擊下一步。單擊「全選」按鈕,然後單擊下一步然後單擊完成並將腳本發送到您選擇的查詢窗口或文件(不要使用剪貼板,因爲它可能是一個大腳本)。 現在刪除所有添加表的腳本,並且應該留下腳本來創建您的外鍵。

    製作該腳本的副本,因爲這是您將數據庫還原到當前狀態的方式。使用搜索和替換將ON DELETE CASCADE添加到每個約束的末尾。這可能會有所不同,這取決於您的FK目前如何設置,您可能需要進行一些手動編輯。

    重複腳本生成,但是這次只設置它只生成DROP語句。 一定要手動刪除生成的表滴。運行下拉菜單,然後運行已編輯的創建,使它們全部級聯刪除。執行刪除操作,再次運行drop腳本,然後運行在開始時保存的腳本。

    另外 - 做你的數據庫第一的備份!即使它只是一個開發數據庫,​​如果腳本的一部分不完全正確,它也會爲您節省一些頭痛。

    希望這會有所幫助!順便提一下,你應該使用完整的測試數據做一些測試,但是我可以看到爲什麼你可能不需要這些測試來進行初始開發。只要不要忘記將其作爲質量保證的一部分。

    7

    除非您想維護Chris提出的所有相關查詢,否則ON DELETE CASCADE是迄今最快和最直接的解決方案。如果你不希望它是永久性的,你爲什麼不有一些T-SQL代碼,將打開和關閉喜歡這裏

    1. 刪除原始Tbl_A_MyFK約束(不ON DELETE該選項CASCADE)

      ALTER TABLE Tbl_A DROP CONSTRAINT Tbl_A_MyFK

    2. 設置約束Tbl_A_MyFK與ON DELETE CASCADE

      ALTER TABLE Tbl_A ADD CONSTRAINT Tbl_A_MyFK FOREIGN KEY (MyFK) REFERENCES Tbl_B(Column) ON DELETE CASCADE

    3. 在這裏你可以做你刪除

      DELETE FROM Tbl_A WHERE ...

    4. 放下你的約束Tbl_A_MyFK

      ALTER TABLE Tbl_A DROP CONSTRAINT Tbl_A_MyFK

    5. 設置約束Tbl_A_MyFK沒有ON DELETE CASCADE

      ALTER TABLE Tbl_A ADD CONSTRAINT Tbl_A_MyFK FOREIGN KEY (MyFK) REFERENCES (Tbl_B)

    1

    後,選擇你必須建立並執行實際刪除

    declare @deleteSql nvarchar(1200) 
    declare delete_cursor cursor for 
    select table_name, criteria 
    from @to_delete 
    order by id desc 
    
    open delete_cursor 
    
    fetch next from delete_cursor 
    into @table_name, @criteria 
    
    while @@fetch_status = 0 
    begin 
    select @deleteSql = 'delete from ' + @table_name + ' where ' + @criteria 
    --print @deleteSql 
    -- exec sp_execute @deleteSql 
    EXEC SP_EXECUTESQL @deleteSql 
    
    fetch next from delete_cursor 
    into @table_name, @criteria 
    end 
    close delete_cursor 
    deallocate delete_cursor 
    
    2

    以接受的答案遠一點,我有必要在不同的模式來做到這一點跨表。我已更新腳本以在輸出的刪除腳本中包含模式。

    CREATE PROCEDURE usp_delete_cascade (
         @base_table_schema varchar(100), @base_table_name varchar(200), @base_criteria nvarchar(1000) 
    ) 
    as begin 
    
         -- 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_schema varchar(100), 
           table_name varchar(200) not null, 
           processed bit not null, 
           delete_sql varchar(1000) 
         ) 
    
         insert into @to_delete (criteria, table_schema, table_name, processed) values (@base_criteria, @base_table_schema, @base_table_name, 0) 
    
         declare @id int, @criteria nvarchar(1000), @table_name varchar(200), @table_schema varchar(100) 
         while exists(select 1 from @to_delete where processed = 0) begin 
           select top 1 @id = id, @criteria = criteria, @table_name = table_name, @table_schema = table_schema from @to_delete where processed = 0 order by id desc 
    
           insert into @to_delete (criteria, table_schema, table_name, processed) 
             select referencing_column.name + ' in (select [' + referenced_column.name + '] from [' + @table_schema + '].[' + @table_name +'] where ' + @criteria + ')', 
               schematable.name, 
               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.schemas schematable on referencing_table.schema_id = schematable.schema_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_schema + '].[' + table_name + '] where ' + criteria from @to_delete order by id desc 
    end 
    
    exec usp_delete_cascade 'schema', 'RootTable', 'Id = 123' 
    exec usp_delete_cascade 'schema', 'RootTable', 'GuidId = ''A7202F84-FA57-4355-B499-1F8718E29058''' 
    
    2

    凱文職位是不完整的,他的T-SQL SP只打印命令,執行這些命令,最後末尾添加此

    DECLARE @commandText VARCHAR(8000) 
         DECLARE curDeletes CURSOR FOR 
          select 'delete from [' + table_name + '] where ' + criteria from @to_delete order by id desc 
    
         OPEN curDeletes 
         FETCH NEXT FROM curDeletes 
         INTO 
          @commandText 
    
         WHILE(@@FETCH_STATUS=0) 
         BEGIN 
          EXEC (@commandText) 
          FETCH NEXT FROM curDeletes INTO @commandText 
         END 
         CLOSE curDeletes 
         DEALLOCATE curDeletes 
    
    5

    之前,這裏有一個人口稀少的優化版本接受的答案的數據模型。它在將它添加到刪除列表之前檢查FK鏈中是否存在數據。我用它來清理測試數據。

    不要在活動的事務性數據庫中使用它 - 它會鎖住太長時間。

    /* 
    -- ============================================================================ 
    -- Purpose: Performs a cascading hard-delete. 
    --   Not for use on an active transactional database- it holds locks for too long. 
    --   (http://stackoverflow.com/questions/116968/in-sql-server-2005-can-i-do-a-cascade-delete-without-setting-the-property-on-my) 
    -- eg: 
    exec dbo.hp_Common_Delete 'tblConsumer', 'Surname = ''TestDxOverdueOneReviewWm''', 1 
    -- ============================================================================ 
    */ 
    create proc [dbo].[hp_Common_Delete] 
    (
        @TableName sysname, 
        @Where nvarchar(4000), -- Shouldn't include 'where' keyword, e.g. Surname = 'smith', NOT where Surname = 'smith' 
        @IsDebug bit = 0 
    ) 
    as 
    set nocount on 
    
    begin try 
        -- Prepare tables to store deletion criteria. 
        -- #tmp_to_delete stores criteria that is tested for results before being added to #to_delete 
        create table #to_delete 
        (
         id int identity(1, 1) primary key not null, 
         criteria nvarchar(4000) not null, 
         table_name sysname not null, 
         processed bit not null default(0) 
        ) 
        create table #tmp_to_delete 
        (
         id int primary key identity(1,1), 
         criteria nvarchar(4000) not null, 
         table_name sysname not null 
        ) 
    
        -- Open a transaction (it'll be a long one- don't use this on production!) 
        -- We need a transaction around criteria generation because we only 
        -- retain criteria that has rows in the db, and we don't want that to change under us. 
        begin tran 
         -- If the top-level table meets the deletion criteria, add it 
         declare @Sql nvarchar(4000) 
         set @Sql = 'if exists(select top(1) * from ' + @TableName + ' where ' + @Where + ') 
          insert #to_delete (criteria, table_name) values (''' + replace(@Where, '''', '''''') + ''', ''' + @TableName + ''')' 
         exec (@Sql) 
    
         -- Loop over deletion table, walking foreign keys to generate delete targets 
         declare @id int, @tmp_id int, @criteria nvarchar(4000), @new_criteria nvarchar(4000), @table_name sysname, @new_table_name sysname 
         while exists(select 1 from #to_delete where processed = 0) 
         begin 
          -- Grab table/criteria to work on 
          select top(1) @id = id, 
            @criteria = criteria, 
            @table_name = table_name 
          from #to_delete 
          where processed = 0 
          order by id desc 
    
          -- Insert all immediate child tables into a temp table for processing 
          insert #tmp_to_delete 
          select referencing_column.name + ' in (select [' + referenced_column.name + '] from [' + @table_name +'] where ' + @criteria + ')', 
            referencing_table.name 
          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 
    
          -- Loop on child table criteria, and insert them into delete table if they have records in the db 
          select @tmp_id = max(id) from #tmp_to_delete 
          while (@tmp_id >= 1) 
          begin 
           select @new_criteria = criteria, @new_table_name = table_name from #tmp_to_delete where id = @tmp_id 
           set @Sql = 'if exists(select top(1) * from ' + @new_table_name + ' where ' + @new_criteria + ') 
            insert #to_delete (criteria, table_name) values (''' + replace(@new_criteria, '''', '''''') + ''', ''' + @new_table_name + ''')' 
           exec (@Sql) 
    
           set @tmp_id = @tmp_id - 1 
          end 
          truncate table #tmp_to_delete 
    
          -- Move to next record 
          update #to_delete 
          set  processed = 1 
          where id = @id 
         end 
    
         -- We have a list of all tables requiring deletion. Actually delete now. 
         select @id = max(id) from #to_delete 
         while (@id >= 1) 
         begin 
          select @criteria = criteria, @table_name = table_name from #to_delete where id = @id 
          set @Sql = 'delete from [' + @table_name + '] where ' + @criteria 
          if (@IsDebug = 1) print @Sql 
          exec (@Sql) 
    
          -- Next record 
          set @id = @id - 1 
         end 
        commit 
    end try 
    
    begin catch 
        -- Any error results in a rollback of the entire job 
        if (@@trancount > 0) rollback 
    
        declare @message nvarchar(2047), @errorProcedure nvarchar(126), @errorMessage nvarchar(2048), @errorNumber int, @errorSeverity int, @errorState int, @errorLine int 
        select @errorProcedure = isnull(error_procedure(), N'hp_Common_Delete'), 
          @errorMessage = isnull(error_message(), N'hp_Common_Delete unable to determine error message'), 
          @errorNumber = error_number(), @errorSeverity = error_severity(), @errorState = error_state(), @errorLine = error_line() 
    
        -- Prepare error information as it would be output in SQL Mgt Studio 
        declare @event nvarchar(2047) 
        select @event = 'Msg ' + isnull(cast(@errorNumber as varchar), 'null') + 
             ', Level ' + isnull(cast(@errorSeverity as varchar), 'null') + 
             ', State ' + isnull(cast(@errorState as varchar), 'null') + 
             ', Procedure ' + isnull(@errorProcedure, 'null') + 
             ', Line ' + isnull(cast(@errorLine as varchar), 'null') + 
             ': ' + isnull(@errorMessage, '@ErrorMessage null') 
        print @event 
    
        -- Re-raise error to ensure admin/job runners understand there was a failure 
        raiserror(@errorMessage, @errorSeverity, @errorState) 
    end catch 
    
    2

    croisharp的回答擴張採取觸發器考慮,即禁止所有影響觸發器,刪除行,並啓用觸發器,即感知模式的解決方案。

    CREATE PROCEDURE usp_delete_cascade (
    @base_table_schema varchar(100), 
    @base_table_name varchar(200), 
    @base_criteria nvarchar(1000) 
    ) 
    as begin 
    
        -- 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_schema varchar(100), 
          table_name varchar(200) not null, 
          processed bit not null, 
          delete_sql varchar(1000) 
        ) 
    
        insert into @to_delete (criteria, table_schema, table_name, processed) values (@base_criteria, @base_table_schema, @base_table_name, 0) 
    
        declare @id int, @criteria nvarchar(1000), @table_name varchar(200), @table_schema varchar(100) 
        while exists(select 1 from @to_delete where processed = 0) begin 
          select top 1 @id = id, @criteria = criteria, @table_name = table_name, @table_schema = table_schema from @to_delete where processed = 0 order by id desc 
    
          insert into @to_delete (criteria, table_schema, table_name, processed) 
            select referencing_column.name + ' in (select [' + referenced_column.name + '] from [' + @table_schema + '].[' + @table_name +'] where ' + @criteria + ')', 
              schematable.name, 
              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.schemas schematable on referencing_table.schema_id = schematable.schema_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_schema + '].[' + table_name + '] where ' + criteria from @to_delete order by id desc 
    
        DECLARE @commandText VARCHAR(8000), @triggerOn VARCHAR(8000), @triggerOff VARCHAR(8000) 
        DECLARE curDeletes CURSOR FOR 
         select 
          'DELETE FROM [' + table_schema + '].[' + table_name + '] WHERE ' + criteria, 
          'ALTER TABLE [' + table_schema + '].[' + table_name + '] DISABLE TRIGGER ALL', 
          'ALTER TABLE [' + table_schema + '].[' + table_name + '] ENABLE TRIGGER ALL' 
         from @to_delete order by id desc 
    
        OPEN curDeletes 
        FETCH NEXT FROM curDeletes INTO @commandText, @triggerOff, @triggerOn 
    
        WHILE(@@FETCH_STATUS=0) 
        BEGIN 
         EXEC (@triggerOff) 
         EXEC (@commandText) 
         EXEC (@triggerOn) 
         FETCH NEXT FROM curDeletes INTO @commandText, @triggerOff, @triggerOn 
        END 
        CLOSE curDeletes 
        DEALLOCATE curDeletes 
    end 
    
    0

    這個腳本有兩個問題:1。 必須註明條件1 = 1,以刪除所有表的基礎。 2.這隻創建與基表的直接關係。如果最終的表具有另一個表父關係時,刪除失敗

    DELETE FROM [DBO]。[表2] WHERE表格ID中(選擇[ID]從[DBO]。[表3],其中1 = 1)

    如果表2有一個父關係表1

    1

    這裏發佈一個腳本,該腳本將與外鍵一起使用,該腳本包含多個列。

    create procedure usp_delete_cascade (
    @TableName varchar(200), @Where nvarchar(1000) 
    ) as begin 
    
    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 default(0), 
        delete_sql varchar(1000) 
    ) 
          DECLARE @MyCursor CURSOR 
    
    declare   @referencing_column_name varchar(1000) 
    declare   @referencing_table_name varchar(1000) 
    declare @Sql nvarchar(4000) 
    insert into @to_delete (criteria, table_name) values ('', @TableName) 
    
    
    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 
         SET @MyCursor = CURSOR FAST_FORWARD 
         FOR 
         select referencing_column.name as column_name, 
          referencing_table.name as table_name 
         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 
    
         OPEN @MyCursor 
         FETCH NEXT FROM @MYCursor 
         INTO @referencing_column_name, @referencing_table_name 
    
         WHILE @@FETCH_STATUS = 0 
    
         BEGIN 
          PRINT @referencing_column_name 
          PRINT @referencing_table_name 
            update @to_delete set criteria = criteria + ' AND '[email protected]_name+'.'[email protected]_column_name+'='+ @referencing_table_name+'.'[email protected]_column_name 
            where table_name = @referencing_table_name 
    
            if(@@ROWCOUNT = 0) 
            BEGIN 
              --if(@id <> 1) 
              --BEGIN 
               insert into @to_delete (criteria, table_name) 
               VALUES(' LEFT JOIN '[email protected]_name+' ON '[email protected]_name+'.'[email protected]_column_name+'='+ @referencing_table_name+'.'[email protected]_column_name+ @criteria, 
               @referencing_table_name 
               ) 
              --END 
              --ELSE 
              --BEGIN 
               --insert into @to_delete (criteria, table_name) 
               --VALUES(' LEFT JOIN '[email protected]_name+' ON '[email protected]_name+'.'[email protected]_column_name+'='+ @referencing_table_name+'.'[email protected]_column_name, 
               [email protected]_table_name 
               --) 
              --END 
            END 
             FETCH NEXT FROM @MYCursor 
          INTO @referencing_column_name, @referencing_table_name 
         END 
    
    
         CLOSE @MyCursor 
         DEALLOCATE @MyCursor 
        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 
    
    --select id, table_name, criteria, @Where from @to_delete order by id desc 
    
    select @id = max(id) from @to_delete 
    while (@id >= 1) 
    begin 
        select @criteria = criteria, @table_name = table_name from @to_delete where id = @id 
        set @Sql = 'delete [' + @table_name + '] from [' + @table_name + '] ' + @criteria+' WHERE '[email protected] 
        exec (@Sql) 
        PRINT @Sql 
    
        -- Next record 
        set @id = @id - 1 
    end 
    end 
    
    相關問題