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