sql server編寫archive通用模板腳本實現自動分批刪除數據【填空式編程】


  博主做過比較多項目的archive腳本編寫,對於這種刪除數據的腳本開發,肯定是一開始的話用最簡單的一個delete語句,然后由於部分表數據量比較大啊,索引比較多啊,會發現刪除數據很慢而且影響系統的正常使用。然后就對delete語句進行按均勻數據量分批delete的改寫,這樣的話,原來的刪除一個表用一個語句,就可能變成幾十行,如果archive的表有十幾個甚至幾十個,那我們的腳本篇幅就非常大了,增加了開發和維護的成本,不利於經驗比較少的新入職同事去開發archive腳本,也容易把注意力分散到所謂分批邏輯中。

  根據這種情況,本周博主(zhang502219048)剛好在工作過程中,總結並編寫了一個自動分批刪除數據的模板,模板固定不變,只需要把注意力集中放在delete語句中,並且可以在delete語句中控制每批刪除的數據量,比較方便,通過變量組裝模板sql,避免每個表就單獨寫一個分批邏輯的重復代碼,化簡為繁,增加分批刪除一個表指定數據的話只需要增加幾行代碼就可以(如下所示中的demo1和demo2)

  demo1:帶參數,根據Date字段是否過期刪除表B對應數據。

  demo2:不帶參數,根據表tmp_Del刪除表A對應ID的數據。

  具體請參考下面的腳本和相關說明,如有不懂的地方歡迎評論或私信咨詢博主。 

-- ===== 1 分批archive模板 =======================================================
--【請不要修改本模板內容】
/* 
說明:
1. 組裝的archive語句為:@sql = @sql_Part1 + @sql_Del + @sql_Part2
2. 組裝的參數@parameters為:@parameters = @parameters_Base + 自定義參數
3. 輸入參數:@strStepInfo 需要print的step信息
4. 輸出參數:@iDeleteCount 總刪除行數
5. archive邏輯專注於@sql_Del,而非分散於分批
*/
declare @sql nvarchar(max),
        @sql_Part1 nvarchar(max),
        @sql_Del nvarchar(max),
        @sql_Part2 nvarchar(max),
        @parameters nvarchar(max),
        @parameters_Base nvarchar(max) = N'@strStepInfo nvarchar(100), @ArchiveDate datetime, @iDeleteCount int out',
        @iDeleteCount int = 0  --作為輸出參數來返回單表刪除總行數

select @sql_Part1 = N'
declare @iBatch int = 1,     --批次
        @iRowCount int = -1  --刪除行數,初始為-1,后面取每批刪除行數@@ROWCOUNT
select @iDeleteCount = 0     --初始化總刪除行數,輸出參數
print convert(varchar(50), getdate(), 121) + @strStepInfo

while @iRowCount <> 0
begin
    print ''begin batch:''
    print @iBatch
    print convert(varchar(50), getdate(), 121)
    
    begin try
        begin tran
'
, @sql_Del = '
            --delete top (50000) 
            --from 表A
            --where Date < @ArchiveDate
'  --@sql_Del的demo腳本是注釋掉的,需要根據實際情況在后續腳本中自行編寫
, @sql_Part2 = N'    
            select @iRowCount = @@rowcount, @iDeleteCount = @iDeleteCount + @@rowcount
        commit tran  
    end try
    begin catch
        rollback tran
        print ''-- Error Message:'' + convert(varchar, error_line()) + '' | '' + error_message()
    end catch

    waitfor delay ''0:00:01'' --延時

    print convert(varchar(50), getdate(), 121)
    print ''end batch''

    select @iBatch = @iBatch + 1
end'

-- ===== 2 demo1(delete語句含參數):archive 表A =======================================================
select @parameters = @parameters_Base  --如果有需要增加自定義參數,在這里加,例如【 + ', @xx datetime'】
, @sql_Del = '
            delete top (50000) 
            from 表A
            where Date < @ArchiveDate
'
select @sql = @sql_Part1 + @sql_Del + @sql_Part2
--print @sql
exec sp_executesql @sql, @parameters, N' 2 archive 表A', @ArchiveDate, @iDeleteCount out  --如果有需要增加自定義參數,在這里加,例如【, @xx】

-- ===== 3 demo2(delete語句不含參數):archive 表B =======================================================
select @parameters = @parameters_Base  --如果有需要增加自定義參數,在這里加,例如【 + ', @xx datetime'】
, @sql_Del = '
            delete top (50000) t_Del
            from 表B t_Del
            inner join tmp_Del td on td.ID = t_Del.ID
'
select @sql = @sql_Part1 + @sql_Del + @sql_Part2
--print @sql
exec sp_executesql @sql, @parameters, N' 3 archive 表B', @ArchiveDate, @iDeleteCount out  --如果有需要增加自定義參數,在這里加,例如【, @xx】

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM