mysql不支持原生for循环,需用while循环配合显式计数器模拟:先declare或set初始化变量,再while判断条件,循环体内用set递增,否则易致死循环或报错。

SQL 里没有原生的 FOR 循环语法,但可以用存储过程 + WHILE 实现等效逻辑;直接写 FOR 会报错,比如 MySQL 报 ERROR 1064,SQL Server 报 Incorrect syntax near 'FOR'。
MySQL 中用 WHILE 模拟 FOR 循环
MySQL 存储过程中不支持 FOR,必须用 WHILE + 显式计数器。关键点是:初始化变量、设置循环条件、手动递增。
常见错误是忘记声明变量作用域或漏掉 SET 递增值,导致死循环或跳过执行。
-
DECLARE变量必须在BEGIN后立即声明,且不能在IF或循环体内重复声明 - 循环变量需用
SET @i = @i + 1(用户变量)或SET i = i + 1(局部变量),混用会出错 - 条件判断用
WHILE i ,不是 <code>FOR i = 1 TO 10—— 后者语法非法
DELIMITER $$ CREATE PROCEDURE loop_example() BEGIN DECLARE i INT DEFAULT 1; WHILE i <h3>SQL Server 中用 WHILE + BREAK/CONTINUE 控制流程</h3><p>SQL Server 同样不支持 <code>FOR</code>,但支持更灵活的流程控制。注意它默认把 <code>@i</code> 当作局部变量,未初始化即使用会得到 <code>NULL</code>,导致循环条件恒假。</p><div class="aritcle_card flexRow artxards"> <div class="artcardd flexRow"> <a class="aritcle_card_img" rel="nofollow" href="/ai/3997" title="Label Studio"><img src="https://img.php.cn/upload/ai_manual/001/246/273/178599594448045.png" alt="Label Studio" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a rel="nofollow" href="/ai/3997" title="Label Studio" class="overflowclass">Label Studio</a> <p class="overflowclass">Label Studio是一款AI数据处理工具,免费开源的数据标注工具。</p> </div> <a rel="nofollow" href="/ai/3997" title="Label Studio" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div><p>容易被忽略的是:SQL Server 的 <code>WHILE</code> 条件为 <code>NULL</code> 时视为 <code>FALSE</code>,所以必须显式 <code>SET @i = 1</code>。</p>
- 用
SET @i = @i + 1更新计数器,不能写成@i += 1(部分版本不支持简写) - 若需提前退出,用
BREAK;跳过当前轮次用CONTINUE,二者只能出现在WHILE块内 - 性能上,每轮都走一次查询或 DML 时,建议批量处理而非逐行循环,否则 I/O 开销明显
CREATE PROCEDURE sp_loop_example AS BEGIN DECLARE @i INT = 1; WHILE @i <h3>PostgreSQL 中用 FOR IN LOOP 遍历结果集(不是数值范围)</h3><p>PostgreSQL 的 <code>FOR</code> 只用于游标或查询结果遍历,比如 <code>FOR rec IN SELECT ... LOOP</code>,它不接受 <code>FOR i IN 1..10 LOOP</code> 这种数值形式(除非用 <code>generate_series()</code> 辅助)。</p><p>误以为能直接写数值 <code>FOR</code> 是常见误解,实际会报 <code>ERROR: syntax error at or near "IN"</code> 或类似提示。</p>
- 要模拟数值循环,得套一层
SELECT * FROM generate_series(1, 5) - 变量
rec是行类型,访问字段用rec.col_name,不是rec[1] - 如果只做简单计数,
generate_series()比手写WHILE更简洁,但不可用于修改数据的上下文(如函数中限制较多)
DO $$
DECLARE
r RECORD;
BEGIN
FOR r IN SELECT * FROM generate_series(1, 3) AS n
LOOP
INSERT INTO log_table (msg) VALUES ('Series: ' || r.n);
END LOOP;
END $$;
真正麻烦的不是“怎么写循环”,而是“该不该用循环”——多数场景下用集合操作(INSERT ... SELECT、窗口函数、CTE)比循环快一个数量级;只有当逻辑强依赖前一次迭代结果(比如累计计算、状态机推进)时,才值得引入存储过程循环。










