博主做過比較多專案的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】
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/236515.html
標籤:其他
上一篇:Mysql—資料庫管理與表管理
下一篇:mysql索引
