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:
如果您觉得我的文章对您有帮助,请关注我的微信公众号,谢谢!

  

原文地址:https://www.cnblogs.com/jason1990/p/8260940.html