SQLServer腳本編寫


臨時接到通知,需要臨時編寫一個SQL Server的腳本,供出差的同事使用一下。

我當時心想這個SQL Server腳本聽都沒聽說過,但是組織說決定就是你了,那我就只能硬着頭皮上了。

 

腳本實現的功能比較簡單,在數據庫中尋找固定前綴的表,表中都包含[Time]屬性,刪除三個月(或者...天)的數據。

簡單搜索了相關知識,分以下幾步實現:

1.獲取時間節點並轉換為指定格式:

  獲取當前日期前指定時間,網上容易百度到,獲取到時間節點需要將其轉換為固定的格式,具體可參考《Sql中把datetime轉換成字符串(CONVERT)》;

  代碼如下所示:

1 select @logdeldate = (select convert(varchar(100), dateadd(month, -3, getdate()), 21));

 

2.獲取數據庫符合要求的指定表:

  此處需要注意獲取到的表名需要存儲進入臨時表中,供后續遍歷使用。因為表中數據沒有主鍵,因此需要進行插入Key以便查詢(如果有更好的辦法,請告知):

1 select NULL tmpKey, [name] into #TempTable from [sysobjects] where [type] = 'u' and name like 'T_Status_A%' order by [name];

  此處臨時表中的數據記錄tmpKey值均為NULL,使用如下語句可以為更新其中一條記錄的tmpKey值:

1 set rowCount 1
2 update #TempTable set tmpKey = 1
3 set rowCount 0

  select rowCount 0的作用為限制接下來執行的SQL語句僅執行一條,比如下一句語句,僅將一條記錄的tmpKey值更新為1。

 1 update #TempTable set tmpKey = 1 

 

3.腳本中聲明變量,並進行賦值操作

1 declare  
2     @i as int,
3     @deldate as varchar(100),     --設備狀態表刪除時間節點
4     @logdeldate as varchar(100),  --日志表刪除時間節點

  上述代碼中聲明了若干變量,並標注其對應類型。

1 select @logdeldate = (select convert(varchar(100), dateadd(month, -3, getdate()), 21));
2 set @logsql = 'delete from [****].[dbo].[T_Log] where Time < ' + CHAR(39) + @logdeldate + CHAR(39);

  上述代碼中對@logdeldate進行賦值,賦值為搜索后的結果;后續設置sql語句給@logsql變量,注意@sql聲明時為@logsql as nvarchar(MAX),,非varchar(MAX)。

  注:CHAR(39)為單引號。

 

4.遍歷結果集,並執行語句

 1 set @i = 0;                        --初始化計數
 2 while @i < @deltablecount
 3     Begin
 4         set rowCount 0
 5         select @tablename = (select [name] from #TempTable where tmpKey = 1)
 6         delete from #TempTable where tmpKey = 1
 7         
 8         set rowCount 1
 9         update #TempTable set tmpKey = 1
10         set rowCount 0
11         
12         set @statussql = 'delete from ' + QUOTENAME(@tablename) + ' where [Time] < ' + CHAR(39) + @deldate + CHAR(39);
13         print @statussql
14         exec(@statussql)
15         Set @i = @i + 1
16     End
17 GO

  上述代碼為遍歷結果集,拼接新的SQL語句並執行。

 

  最后附上此次的腳本,因為初次編寫,有諸多不滿意之處,但是也不知道如何改進,如果各位看后有改進方法請告知。

  最后附上完整代碼:

--刪除數據庫指定日期數據前,請確認操作不可逆轉
USE [****] 
GO

---------------------------------------------------------------------------------------------------------------------------------------

--選取符合要求的表,存儲進臨時表中供后續遍歷
select NULL tmpKey, [name] into #TempTable from [sysobjects] where [type] = 'u' and name like 'T_Status_A%' order by [name];
GO

set rowCount 1
update #TempTable set tmpKey = 1
set rowCount 0

---------------------------------------------------------------------------------------------------------------------------------------

declare  
    @i as int,
    @deldate as varchar(100),     --狀態表刪除時間節點
    @logdeldate as varchar(100),  --日志表刪除時間節點
    @tablename as varchar(100),
    @deltablecount as int,        --需要刪除的數據庫總數
    @logsql as nvarchar(MAX),
    @realsql as nvarchar(MAX),
    @statussql as nvarchar(MAX);
    
select @deltablecount = COUNT(*) from #TempTable;

---------------------------------------------------------------------------------------------------------------------------------------

--設置日志表的刪除時間節點(默認刪除三個月以前的數據)
select @logdeldate = (select convert(varchar(100), dateadd(month, -3, getdate()), 21));
set @logsql = 'delete from [****].[dbo].[T_Log] where Time < ' + CHAR(39) + @logdeldate + CHAR(39);
print(@logsql)
exec(@logsql) 

---------------------------------------------------------------------------------------------------------------------------------------

--設置設備狀態表刪除時間(默認刪除三個月以前的數據)
select @deldate = (select convert(varchar(100), dateadd(month, -3, getdate()), 21));

set @i = 0;                        --初始化計數
while @i < @deltablecount
    Begin
        set rowCount 0
        select @tablename = (select [name] from #TempTable where tmpKey = 1)
        delete from #TempTable where tmpKey = 1
        
        set rowCount 1
        update #TempTable set tmpKey = 1
        set rowCount 0
        
        set @statussql = 'delete from ' + QUOTENAME(@tablename) + ' where [Time] < ' + CHAR(39) + @deldate + CHAR(39);
        print @statussql
        exec(@statussql)
        Set @i = @i + 1
    End
GO

drop table #TempTable
GO

 

 

PS:
如果您覺得我的文章對您有幫助,請關注我的微信公眾號,謝謝!

 

 

  

 


免責聲明!

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



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