LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

SQL中while循环的用法

admin
2025年12月29日 20:7 本文热度 424

在 SQL 的集合思维世界里,我们总说要避免“逐行处理”。但有时候,你确实需要一个接一个地处理某些事情。比如:批量更新数据、逐行调用存储过程、或者执行一些需要重复的逻辑。

这时候,WHILE 循环就登场了。它是 SQL 里最基础的流程控制语句,能让你重复执行一段代码块,直到某个条件不再满足。

一、WHILE循环长什么样

先看看它的基本结构:

DECLARE @counter INT = 1;  -- 初始化计数器

WHILE @counter <= 5        -- 循环条件:当计数器小于等于5时
BEGIN
    PRINT '这是第 ' + CAST(@counter AS VARCHAR) + ' 次循环';
    SET @counter = @counter + 1;  -- 千万不要忘了改变条件,否则...
END

PRINT '循环结束!';

运行结果:

这是第 1 次循环
这是第 2 次循环
这是第 3 次循环
这是第 4 次循环
这是第 5 次循环
循环结束!

关键点:

  1. WHILE (条件):条件为真就继续循环,为假就退出。
  2. BEGIN...END:包裹要重复执行的代码块(如果只有一行,可以省略,但强烈建议总是加上)。
  3. 必须要有改变循环条件的语句,否则就是无限循环(我们稍后会说这个)。

二、数据批处理

这是 WHILE 循环最常见、最实用的场景。假设你要更新一个百万级别的表,直接一个 UPDATE 可能锁表太久,影响生产环境。这时可以分批处理。

场景:给所有员工涨薪5%,但每次只更新1000条

-- 假设我们有 Employees 表
CREATETABLE#Employees (
    EmployeeID INT PRIMARY KEY,
    Salary DECIMAL(10,2)
);

-- 插入10万条测试数据(实际中你的表可能已有数据)
DECLARE @i INT = 1;
WHILE @i <= 100000
BEGIN
    INSERTINTO#Employees VALUES (@i, 5000.00);
    SET @i = @i + 1;
END

-- 现在开始分批涨薪
DECLARE @BatchSize INT = 1000;  -- 每批处理1000条
DECLARE @ProcessedRows INT = 1-- 已处理行数
DECLARE @TotalRows INT;

SELECT @TotalRows = COUNT(*) FROM#Employees;  -- 总行数

WHILE @ProcessedRows <= @TotalRows
BEGIN
    -- 更新当前批次
    UPDATE TOP (@BatchSize) #Employees
    SET Salary = Salary * 1.05-- 涨薪5%
    WHERE EmployeeID BETWEEN @ProcessedRows AND @ProcessedRows + @BatchSize - 1;
    
    PRINT '已处理 ' + CAST(@BatchSize AS VARCHAR) + ' 条记录,当前进度:' 
          + CAST(@ProcessedRows AS VARCHAR) + '/' + CAST(@TotalRows AS VARCHAR);
    
    -- 关键:更新已处理行数
    SET @ProcessedRows = @ProcessedRows + @BatchSize;
    
    -- 可选:每批之间稍微暂停一下,减轻服务器压力
    WAITFOR DELAY '00:00:00.100';  -- 暂停0.1秒
END

PRINT '批量涨薪完成!';

这样做的优点:

  • 减少锁竞争:每次只锁一小部分数据,其他事务可以访问表的其他部分。
  • 可控的事务大小:避免单个巨大事务填满日志文件。
  • 可以随时看到进度:通过 PRINT 语句。
  • 可以中断:如果发现问题,可以停止脚本,不会全部回滚。

三、WHILE循环的“好朋友”:BREAK 和 CONTINUE

有时候你需要更精细地控制循环。

  1. BREAK:立即退出循环
DECLARE @i INT = 1;
WHILE @i <= 10
BEGIN
    IF @i = 6
    BEGIN
        PRINT '遇到6,提前退出!';
        BREAK;  -- 直接跳出循环
    END
    
    PRINT '当前值:' + CAST(@i AS VARCHAR);
    SET @i = @i + 1;
END
-- 只会打印1到5,然后退出
  1. CONTINUE:跳过本次循环的剩余代码
DECLARE @i INT = 0;
WHILE @i < 10
BEGIN
    SET @i = @i + 1;
    
    IF @i % 2 = 0  -- 如果是偶数
    BEGIN
        PRINT '跳过偶数:' + CAST(@i ASVARCHAR);
        CONTINUE;  -- 跳过下面的代码,直接开始下一次循环
    END
    
    PRINT '处理奇数:' + CAST(@i ASVARCHAR);
END
-- 会打印所有奇数,但偶数只打印“跳过偶数”

四、WHILE循环的“噩梦”:无限循环

忘记更新循环条件是最常见的错误:

-- ⚠️ 危险代码!不要在生产环境运行!
DECLARE @i INT = 1;
WHILE @i <= 5  -- 条件永远为真,因为@i从未改变
BEGIN
    PRINT '无限循环...';
    -- 忘记写:SET @i = @i + 1;
END

防御措施: 总是为循环设置安全上限:

DECLARE @i INT = 1;
DECLARE @SafetyCounter INT = 0;

WHILE @i <= 1000000 AND @SafetyCounter < 1000  -- 安全阀:最多1000次
BEGIN
    -- 你的业务逻辑...
    
    SET @i = @i + 1;
    SET @SafetyCounter = @SafetyCounter + 1;
END

IF @SafetyCounter >= 1000
    PRINT '警告:达到安全上限,循环可能有问题!';

五、WHILE vs 游标:什么时候用哪个?

很多人用 WHILE 来实现游标的功能,但两者有区别:

特性
WHILE循环
游标(CURSOR)
控制方式
基于条件表达式
基于结果集遍历
典型用途
批处理、重复操作
逐行复杂处理
性能
通常更好
通常较差
代码复杂度
相对简单
更复杂(声明、打开、获取、关闭)

简单原则:

  • 如果需要逐行进行非常复杂的业务逻辑,可能用游标。
  • 如果只是重复执行某个操作直到条件满足,用 WHILE
  • 如果能用基于集合的操作(一句UPDATE),永远不要用 WHILE 或游标。

六、一个有趣的例子:生成日期序列

-- 生成2024年5月1日到5月31日的所有日期
DECLARE @StartDate DATE = '2024-05-01';
DECLARE @EndDate DATE = '2024-05-31';

CREATETABLE#DateList (TheDate DATE);

WHILE @StartDate <= @EndDate
BEGIN
    INSERTINTO#DateList VALUES (@StartDate);
    SET @StartDate = DATEADD(DAY1, @StartDate);  -- 日期加1天
END

SELECT * FROM#DateList ORDER BY TheDate;
DROPTABLE#DateList;

总结:WHILE循环的正确打开方式

  1. 先问自己:这个问题真的不能用集合操作解决吗?
  2. 如果必须用WHILE
    • 明确循环条件退出条件
    • 记得在循环体内改变循环条件
    • 考虑添加安全计数器防止无限循环
    • 对于数据操作,尽量批量处理而不是逐行
  3. 测试:先在测试环境用小数据量跑通

WHILE 循环就像 SQL 工具箱里的“手动挡”。自动挡(集合操作)开起来更爽,但在某些特殊路况下,手动挡能给你更精细的控制。


阅读原文:原文链接


该文章在 2025/12/31 10:26:45 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved