再说说基于联接的DELETE,T-SQL支持一种基于联接的DELETE语法,这不是一种标准的SQL语法。联接本身就有过虑的作用,因为它有一个基于谓词的过滤器(ON子句)。通过联接可以访问另一个表中相关行的属性(列),并在WHERE子句中引用这些属性,这就意味着可以根据对另一个表中相关行的属性定义的过虑器来删除表中的数据行。例如:
DELETE FROM S5 |
这和SELECT语句非常相似,DELETE语句在逻辑上第一个处理的子句是FROM子句(第二行FROM dbo.S5_BinTest_Info AS S5的这个),接着处理WHERE子句,最后才是DELETE子句。
这也可以用查询子句来实现同样的处理:
DELETE FROM dbo.S5_BinTest_Info WHERE EXISTS(SELECT 1 FROM dbo.S5_BinTest_Info_Dtl AS DTL WHERE S5_BinTest_Info .ID=DTL.ID AND DTL.QTY=1); |
这里的查询子句的方式是标准的SQL语句,我更喜欢使用标准SQL。
再回到我这个工作中的问题,我想用分批删除的方式来处理。一次删除合理数据的记录,多删除几次就可以了。
由于我为里是有ID的,所以一次删除一个ID号的记录,以下是更改后的循环方式实现源码。
1: --2012-03-30,因删除大数据问题,以下更改为分批删除的方式实现 2: DECLARE @MINID INT; 3: DECLARE @N INT; 4: --取出要删除的90天前的记录的ID 5: SELECT BinTestID into #S5ID 6: from dbo.S5_BinTest_Info 7: where TS <dateadd(dd,-90,getdate()); 8: --以要删除的ID数量为循环变量,因为ID号可能不连续 9: SELECT @N=(SELECT COUNT(1) FROM #S5ID); 10: WHILE (@N>0) 11: BEGIN 12: -- 一次删除一个ID对应的数据 13: SELECT @MINID=MIN(BinTestID) FROM #S5ID; 14: DELETE FROM dbo.S5_BinTest_Detail 15: where BinTestID=@MINID; 16: DELETE from dbo.S5_BinTest_Info 17: where BinTestID=@MINID; 18: --从临时表中去除已删除的ID号 19: DELETE #S5ID WHERE BinTestID=@MINID; 20: --更改剩余要删除的ID数,这是循环变量 21: SELECT @N=(SELECT COUNT(1) FROM #S5ID); 22: END 23: DROP TABLE #S5ID; |
如果对于没有ID的数据表,我们可以用TOP的方式来删除。
我使用这样的方式执行时,日志基本没有增长,因为删除一次很少的数据,成功后会释放,再使用。
您,删除数据时考虑语法和条件还有大量数据的日志增长空间问题了吗?