想写一个存储过程删除100多张表,每个表要删除几万条记录

时间:2021-06-02 23:23:49
想写一个存储过程删除100多张表,每个表要删除几万条记录
--------------------------------------
存储过程的参数就是 日期 字符串。即程序将删除这个日期之前的多个表格的记录

如以下是调用的方式:
exec 数据清理 '2012-12-31'

但是我在存储过程中要写上每张表的删除代码,如:

delete tab1 where 月份 <=@strdate
delete tab23 where 月份 <=@strdate

但是,这样的语句有1百多条呀。每条语句就要执行很长一段时间。

我就怕, 我的程序一执行,数据库会不会瘫掉呀。
但是,语句之间又不能加上 go 语句,因为,加上go就不能识别我的参数了。

我是写一个程序,给另一家公司用,我上次清理是一条一条手动执行的,他们自己清理,只能写成存储过程让他们调用了。
但是,我就怕数据库会瘫痪呀,我没有这么大数据量的处理经验呀。
再说,他们的数据库服务器,很慢,很老了。
数据库 10多个 G 了



7 个解决方案

#1


每删一个表(的部分记录),就提交一次

#2


引用 1 楼 sz_haitao 的回复:
每删一个表(的部分记录),就提交一次

谢谢,如何提交呢?
go 语句就是提交的功能吧,但是我没法用呀
多个【批】不能共享一个参数呀?

#3


BEGIN TRAN T1
delete t1 ...
COMMIT TRAN T1

BEGIN TRAN T1
delete t2 ...
COMMIT TRAN T1

...

#4



--才几万数据 直接删除就行啦
--而且可以转移到历史数据库里 这个是转移历史数据库的脚本 先插入到历史数据库 再删除数据
--我这里有脚本 给你 你改改就可以了
--F_SQLWHERE  F_SQLAND 是特定的条件 
--TableOrder
USE [DeliveryCenter]
IF(OBJECT_ID('T_DeliveryCenter_hty_TableOrder'))IS NOT NULL    
DROP TABLE T_DeliveryCenter_hty_TableOrder    
CREATE TABLE T_DeliveryCenter_hty_TableOrder    
(F_ID INT IDENTITY(1,1),    
F_TableName VARCHAR(100),    
F_Type INT,    
F_SQLWHERE VARCHAR(1000),    
F_SQLAND VARCHAR(1000),   
F_ColumnName VARCHAR(1000), 
F_IDENTITY INT DEFAULT 0,
F_Count INT      
)    

--PROC

CREATE PROC  P_DeliveryCenter_TransferHistory         
/*      
过程功能:        
1.实现指定表明转移历史数据       
2.脚本灵活 可指表明 保留数据天数 删除数据次数--暂定每次删除5W行数据       
3.删除已转移数据次数根据转移数据行数决定      
创建人: 汤南冰        
创建时间:2011-11-10        
*/       
AS           
DECLARE @Type INT             
DECLARE @I INT      
DECLARE @COUNT INT       
DECLARE @COUNT_I INT       
DECLARE @COUNT_TableName VARCHAR(100)      
DECLARE @COUNT_SQL NVARCHAR(MAX)       
DECLARE @TableName VARCHAR(100)            
DECLARE @SQL VARCHAR(1000)            
DECLARE @SQLWHERE VARCHAR(1000)            
DECLARE @SQLAND VARCHAR(1000)    
DECLARE @ColumnName VARCHAR(MAX)            
DECLARE @DateTime VARCHAR(100)            
DECLARE @IDENTITY INT             
DECLARE @DELETE_SQL VARCHAR(1000)          
DECLARE @DELETE_COUNT INT         
DECLARE @DELETE_I INT      
      
SET @I=1             
WHILE @I<=(SELECT MAX(F_ID)FROM [DeliveryCenter]..T_DeliveryCenter_hty_TableOrder WITH(NOLOCK))            
BEGIN            
  SET @COUNT_TableName =(SELECT F_TableName FROM [DeliveryCenter]..T_DeliveryCenter_hty_TableOrder WITH(NOLOCK) WHERE F_ID=@I)       
  SET @TableName =(SELECT F_TableName FROM [DeliveryCenter]..T_DeliveryCenter_hty_TableOrder WITH(NOLOCK) WHERE F_ID=@I)            
  SET @Type=(SELECT F_Type FROM [DeliveryCenter]..T_DeliveryCenter_hty_TableOrder WITH(NOLOCK) WHERE F_ID=@I)            
  SET @DateTime =CAST((CONVERT(CHAR(10),DATEADD(DAY,-@Type,GETDATE()),120))AS CHAR(10))            
  SET @SQLWHERE =(SELECT F_SQLWHERE FROM [DeliveryCenter]..T_DeliveryCenter_hty_TableOrder WITH(NOLOCK) WHERE F_ID=@I)            
  SET @SQLAND =(SELECT F_SQLAND FROM [DeliveryCenter]..T_DeliveryCenter_hty_TableOrder WITH(NOLOCK) WHERE F_ID=@I)      
  SET @ColumnName =  (SELECT F_ColumnName FROM [DeliveryCenter]..T_DeliveryCenter_hty_TableOrder WITH(NOLOCK) WHERE F_ID=@I)                 
  SET @IDENTITY =(SELECT F_IDENTITY FROM [DeliveryCenter]..T_DeliveryCenter_hty_TableOrder WITH(NOLOCK) WHERE F_ID=@I )       
        
  BEGIN       
  SET @COUNT_SQL= 'SELECT @COUNT=COUNT(1) FROM '+@COUNT_TableName + @SQLWHERE +''''+@DateTime+''''+@SQLAND         
  EXEC SP_EXECUTESQL @COUNT_SQL, N'@COUNT INT OUTPUT',@COUNT OUTPUT      
  UPDATE  [DeliveryCenter]..T_DeliveryCenter_hty_TableOrder  SET F_COUNT =@COUNT WHERE F_ID=@I      
 SET @SQL= '            
    INSERT INTO '+'[DeliveryCenter_hty]..'+@TableName  +'('+@ColumnName+')' +' SELECT'+@ColumnName+'  FROM [DeliveryCenter]..'+@TableName +' WITH(NOLOCK) ' + @SQLWHERE            
    +''''+@DateTime+''''+@SQLAND            
     EXEC (@SQL)      
     SET  @DELETE_I =(SELECT F_COUNT/50000 FROM [DeliveryCenter]..T_DeliveryCenter_hty_TableOrder WITH(NOLOCK) WHERE F_TableName=@TableName)+1        
     WHILE @DELETE_I>=1        
     BEGIN         
     SET @DELETE_SQL ='DELETE TOP (50000) FROM '+'DeliveryCenter..'+@TableName+@SQLWHERE+''''+@DateTime+''''+@SQLAND          
     EXEC (@DELETE_SQL)        
     SET @DELETE_I=@DELETE_I-1        
     END        
  END      
      
        
 SET @I=@I+1      
END 

#5


楼上高手,有点看不懂,是新建一个库,作为历史数据库吗?

#6


该回复于2012-02-28 08:43:50被版主删除

#7




--建存储过程
create proc delete_table_his
@strdate datetime
as
begin

select name,IDENTITY(int,1,1) as num_id into #temp from sys.tables 
where name like 'tab%'--这里是要把你所有要删除月份的表都找出来,你的逻辑我不懂,我只是随便写写,注意,别弄错了,删除不该删的表

declare @delete_num int
set @delete_num=1
while (@delete_num<=select max(num_id) from #temp)
begin 

declare @delete_table varchar(200)

set @delete_table=(select name from #temp where delete_num=@delete_num)

exec ('delete '+@delete_table+' where 月份 <='+@strdate)

set @delete_num=@delete_num+1
end

end

#1


每删一个表(的部分记录),就提交一次

#2


引用 1 楼 sz_haitao 的回复:
每删一个表(的部分记录),就提交一次

谢谢,如何提交呢?
go 语句就是提交的功能吧,但是我没法用呀
多个【批】不能共享一个参数呀?

#3


BEGIN TRAN T1
delete t1 ...
COMMIT TRAN T1

BEGIN TRAN T1
delete t2 ...
COMMIT TRAN T1

...

#4



--才几万数据 直接删除就行啦
--而且可以转移到历史数据库里 这个是转移历史数据库的脚本 先插入到历史数据库 再删除数据
--我这里有脚本 给你 你改改就可以了
--F_SQLWHERE  F_SQLAND 是特定的条件 
--TableOrder
USE [DeliveryCenter]
IF(OBJECT_ID('T_DeliveryCenter_hty_TableOrder'))IS NOT NULL    
DROP TABLE T_DeliveryCenter_hty_TableOrder    
CREATE TABLE T_DeliveryCenter_hty_TableOrder    
(F_ID INT IDENTITY(1,1),    
F_TableName VARCHAR(100),    
F_Type INT,    
F_SQLWHERE VARCHAR(1000),    
F_SQLAND VARCHAR(1000),   
F_ColumnName VARCHAR(1000), 
F_IDENTITY INT DEFAULT 0,
F_Count INT      
)    

--PROC

CREATE PROC  P_DeliveryCenter_TransferHistory         
/*      
过程功能:        
1.实现指定表明转移历史数据       
2.脚本灵活 可指表明 保留数据天数 删除数据次数--暂定每次删除5W行数据       
3.删除已转移数据次数根据转移数据行数决定      
创建人: 汤南冰        
创建时间:2011-11-10        
*/       
AS           
DECLARE @Type INT             
DECLARE @I INT      
DECLARE @COUNT INT       
DECLARE @COUNT_I INT       
DECLARE @COUNT_TableName VARCHAR(100)      
DECLARE @COUNT_SQL NVARCHAR(MAX)       
DECLARE @TableName VARCHAR(100)            
DECLARE @SQL VARCHAR(1000)            
DECLARE @SQLWHERE VARCHAR(1000)            
DECLARE @SQLAND VARCHAR(1000)    
DECLARE @ColumnName VARCHAR(MAX)            
DECLARE @DateTime VARCHAR(100)            
DECLARE @IDENTITY INT             
DECLARE @DELETE_SQL VARCHAR(1000)          
DECLARE @DELETE_COUNT INT         
DECLARE @DELETE_I INT      
      
SET @I=1             
WHILE @I<=(SELECT MAX(F_ID)FROM [DeliveryCenter]..T_DeliveryCenter_hty_TableOrder WITH(NOLOCK))            
BEGIN            
  SET @COUNT_TableName =(SELECT F_TableName FROM [DeliveryCenter]..T_DeliveryCenter_hty_TableOrder WITH(NOLOCK) WHERE F_ID=@I)       
  SET @TableName =(SELECT F_TableName FROM [DeliveryCenter]..T_DeliveryCenter_hty_TableOrder WITH(NOLOCK) WHERE F_ID=@I)            
  SET @Type=(SELECT F_Type FROM [DeliveryCenter]..T_DeliveryCenter_hty_TableOrder WITH(NOLOCK) WHERE F_ID=@I)            
  SET @DateTime =CAST((CONVERT(CHAR(10),DATEADD(DAY,-@Type,GETDATE()),120))AS CHAR(10))            
  SET @SQLWHERE =(SELECT F_SQLWHERE FROM [DeliveryCenter]..T_DeliveryCenter_hty_TableOrder WITH(NOLOCK) WHERE F_ID=@I)            
  SET @SQLAND =(SELECT F_SQLAND FROM [DeliveryCenter]..T_DeliveryCenter_hty_TableOrder WITH(NOLOCK) WHERE F_ID=@I)      
  SET @ColumnName =  (SELECT F_ColumnName FROM [DeliveryCenter]..T_DeliveryCenter_hty_TableOrder WITH(NOLOCK) WHERE F_ID=@I)                 
  SET @IDENTITY =(SELECT F_IDENTITY FROM [DeliveryCenter]..T_DeliveryCenter_hty_TableOrder WITH(NOLOCK) WHERE F_ID=@I )       
        
  BEGIN       
  SET @COUNT_SQL= 'SELECT @COUNT=COUNT(1) FROM '+@COUNT_TableName + @SQLWHERE +''''+@DateTime+''''+@SQLAND         
  EXEC SP_EXECUTESQL @COUNT_SQL, N'@COUNT INT OUTPUT',@COUNT OUTPUT      
  UPDATE  [DeliveryCenter]..T_DeliveryCenter_hty_TableOrder  SET F_COUNT =@COUNT WHERE F_ID=@I      
 SET @SQL= '            
    INSERT INTO '+'[DeliveryCenter_hty]..'+@TableName  +'('+@ColumnName+')' +' SELECT'+@ColumnName+'  FROM [DeliveryCenter]..'+@TableName +' WITH(NOLOCK) ' + @SQLWHERE            
    +''''+@DateTime+''''+@SQLAND            
     EXEC (@SQL)      
     SET  @DELETE_I =(SELECT F_COUNT/50000 FROM [DeliveryCenter]..T_DeliveryCenter_hty_TableOrder WITH(NOLOCK) WHERE F_TableName=@TableName)+1        
     WHILE @DELETE_I>=1        
     BEGIN         
     SET @DELETE_SQL ='DELETE TOP (50000) FROM '+'DeliveryCenter..'+@TableName+@SQLWHERE+''''+@DateTime+''''+@SQLAND          
     EXEC (@DELETE_SQL)        
     SET @DELETE_I=@DELETE_I-1        
     END        
  END      
      
        
 SET @I=@I+1      
END 

#5


楼上高手,有点看不懂,是新建一个库,作为历史数据库吗?

#6


该回复于2012-02-28 08:43:50被版主删除

#7




--建存储过程
create proc delete_table_his
@strdate datetime
as
begin

select name,IDENTITY(int,1,1) as num_id into #temp from sys.tables 
where name like 'tab%'--这里是要把你所有要删除月份的表都找出来,你的逻辑我不懂,我只是随便写写,注意,别弄错了,删除不该删的表

declare @delete_num int
set @delete_num=1
while (@delete_num<=select max(num_id) from #temp)
begin 

declare @delete_table varchar(200)

set @delete_table=(select name from #temp where delete_num=@delete_num)

exec ('delete '+@delete_table+' where 月份 <='+@strdate)

set @delete_num=@delete_num+1
end

end