You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL批量循环删除数据:统计总删除条数并邮件发送的实现

批量清理历史数据并统计发送邮件方案

核心思路

提前初始化统计用的临时表(避免循环中重复创建报错),对每张表执行批量删除逻辑并累计删除条数,最后将统计结果生成邮件发送。


1. 初始化统计临时表

在所有清理逻辑前创建本地临时表,循环中仅插入数据而非重复建表:

-- 创建统计结果存储表(仅执行一次)
CREATE TABLE #DeleteStats (
    TableName NVARCHAR(128),
    DeleteCount INT
)

2. 单表批量删除+统计实现

以清理指定时间前的数据为例,每次批量删除500条,累计统计总删除数:

DECLARE @TableName NVARCHAR(128) = 'TableA'
DECLARE @BatchSize INT = 500
DECLARE @TotalDeleted INT = 0
DECLARE @DeletedCount INT = 0

WHILE 1=1
BEGIN
    -- 加ROWLOCK提示缩小锁范围,降低对业务的影响
    DELETE TOP(@BatchSize) WITH (ROWLOCK)
    FROM TableA
    WHERE CreatedTime < '2023-01-01' -- 替换为你的清理条件
    
    SET @DeletedCount = @@ROWCOUNT
    SET @TotalDeleted += @DeletedCount

    -- 没有数据可删时退出循环
    IF @DeletedCount = 0
        BREAK
END

-- 将当前表的统计结果插入临时表
INSERT INTO #DeleteStats (TableName, DeleteCount)
VALUES (@TableName, @TotalDeleted)

3. 多表批量处理方案

如果需要清理多张表,可通过游标遍历预定义的表列表,批量执行清理逻辑:

-- 定义需清理的表及对应过滤条件
CREATE TABLE #TablesToClean (
    TableName NVARCHAR(128),
    FilterCondition NVARCHAR(MAX)
)

INSERT INTO #TablesToClean
VALUES 
('TableA', 'CreatedTime < ''2023-01-01'''),
('TableB', 'ExpireTime < GETDATE()'),
('TableC', 'Id < 100000')

-- 游标遍历处理每张表
DECLARE @CurrentTable NVARCHAR(128), @Filter NVARCHAR(MAX)
DECLARE TableCursor CURSOR FOR
SELECT TableName, FilterCondition FROM #TablesToClean

OPEN TableCursor
FETCH NEXT FROM TableCursor INTO @CurrentTable, @Filter

WHILE @@FETCH_STATUS = 0
BEGIN
    DECLARE @TotalDeleted INT = 0
    DECLARE @DeletedCount INT = 0
    DECLARE @Sql NVARCHAR(MAX)

    WHILE 1=1
    BEGIN
        -- 动态SQL执行批量删除,用QUOTENAME避免注入风险
        SET @Sql = N'
        DELETE TOP(500) WITH (ROWLOCK)
        FROM ' + QUOTENAME(@CurrentTable) + '
        WHERE ' + @Filter + '
        SET @DeletedCount = @@ROWCOUNT'

        EXEC sp_executesql @Sql, N'@DeletedCount INT OUTPUT', @DeletedCount OUTPUT

        SET @TotalDeleted += @DeletedCount

        IF @DeletedCount = 0
            BREAK
    END

    -- 插入当前表的统计结果
    INSERT INTO #DeleteStats (TableName, DeleteCount)
    VALUES (@CurrentTable, @TotalDeleted)

    FETCH NEXT FROM TableCursor INTO @CurrentTable, @Filter
END

CLOSE TableCursor
DEALLOCATE TableCursor

4. 生成邮件并发送

将统计结果拼接为HTML格式邮件,通过SQL Server的邮件功能发送:

DECLARE @MailBody NVARCHAR(MAX)

-- 构建HTML邮件内容
SET @MailBody = N'
<h3>历史数据清理统计报告</h3>
<table border="1" cellpadding="4" cellspacing="0">
    <tr>
        <th>数据表名</th>
        <th>删除记录总数</th>
    </tr>'

SELECT @MailBody += N'
    <tr>
        <td>' + TableName + '</td>
        <td>' + CAST(DeleteCount AS NVARCHAR(20)) + '</td>
    </tr>'
FROM #DeleteStats

SET @MailBody += N'
</table>'

-- 发送邮件(替换为你的邮件配置和收件人)
EXEC msdb.dbo.sp_send_dbmail
    @profile_name = '你的邮件配置文件名',
    @recipients = '收件人邮箱@xxx.com',
    @subject = '历史数据清理完成通知',
    @body = @MailBody,
    @body_format = 'HTML'

5. 清理临时表

执行完成后删除临时表释放资源:

DROP TABLE #DeleteStats
DROP TABLE #TablesToClean

关键注意事项

  • 批量删除的TOP值(示例中为500)可根据数据库性能调整,避免长时间锁表。
  • 动态SQL必须用QUOTENAME()处理表名,防止SQL注入。
  • 生产环境建议在低峰期执行,或搭配事务控制(若需保证数据一致性)。

内容的提问来源于stack exchange,提问作者PrettyCode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 06:47:57