CodeGym /课程 /SQL SELF /在PL/pgSQL中使用循环:LOOP、FOR、WHILE

在PL/pgSQL中使用循环:LOOP、FOR、WHILE

SQL SELF
第 51 级, 课程 1
可用

循环可以让你把一段代码重复执行好多次,只要满足某个条件,或者遍历某个数据集。这对于自动化任务、处理大量数据或者做重复操作特别有用。

想象一下,你要手动给小组里的每个小孩发糖果。那肯定乱套了!其实你可以遍历小孩名单,依次给每个人发一颗糖。在这个场景里,“遍历名单”就是循环。

PostgreSQL支持几种循环:

  1. LOOP —— 通用循环,一直执行,直到你手动让它停下来。
  2. FOR —— 按照数字范围或者查询结果,执行指定次数的循环。
  3. WHILE —— 只要条件成立就一直循环。

我们来一个个看下每种循环。

无限循环:LOOP

LOOP是PL/pgSQL里最基础的循环形式,会一直重复执行代码块。这个循环会无限执行,得用EXIT命令手动跳出来。

语法:

LOOP
    -- 你的代码写这里
END LOOP;

举个例子。用LOOP算1到10的和:

DO $$
DECLARE
    counter INT := 1;
    sum INT := 0;
BEGIN
    LOOP
        sum := sum + counter; -- 加上当前计数器的值
        counter := counter + 1; -- 计数器+1

        -- 如果计数器大于10就退出循环
        IF counter > 10 THEN
            EXIT;
        END IF;
    END LOOP;

    RAISE NOTICE '1到10的和: %', sum;
END $$;
  1. 变量counter每次循环都会加1。
  2. 条件IF counter > 10 THEN EXIT;让计数器超过10时跳出循环。
  3. 最后输出所有数字的和。

遍历范围或数据集的循环:FOR

第二种循环,FOR,用来遍历:

  1. 数字范围。
  2. SQL查询结果。

遍历数字范围的循环

语法:

FOR variable IN [REVERSE] start..end LOOP
    -- 你的代码写这里
END LOOP;

输出1到5的数字:

DO $$
BEGIN
    FOR i IN 1..5 LOOP
        RAISE NOTICE '当前值: %', i;
    END LOOP;
END $$;

反向遍历的例子:

DO $$
BEGIN
    FOR i IN REVERSE 5..1 LOOP
        RAISE NOTICE '反向顺序: %', i;
    END LOOP;
END $$;

遍历SQL查询结果的循环

这个方式很适合处理表里的每一行。

语法:

FOR variable IN QUERY (SELECT ...) LOOP
    -- 你的代码写这里
END LOOP;

举个遍历students表的例子:

DO $$
DECLARE
    student_name TEXT;
BEGIN
    FOR student_name IN QUERY (SELECT name FROM students) LOOP
        RAISE NOTICE '你好, %!', student_name;
    END LOOP;
END $$;

条件循环:WHILE

WHILE会一直执行,直到条件不成立为止。

语法:

WHILE 条件 LOOP
    -- 你的代码写这里
END LOOP;

用WHILE算1到10的和:

DO $$
DECLARE
    counter INT := 1;
    sum INT := 0;
BEGIN
    WHILE counter <= 10 LOOP
        sum := sum + counter;
        counter := counter + 1;
    END LOOP;

    RAISE NOTICE '1到10的和: %', sum;
END $$;

生活中的例子

现在我们已经搞懂循环的基础了,来看看实际应用的例子。

例子1:生成乘法表

DO $$
DECLARE
    i INT;
    j INT;
BEGIN
    FOR i IN 1..5 LOOP
        FOR j IN 1..5 LOOP
            RAISE NOTICE '% x % = %', i, j, i * j;
        END LOOP;
    END LOOP;
END $$;

例子2:遍历查询结果。 假设我们有个products表,字段有id和price。我们把所有价格都涨10%。

DO $$
DECLARE
    prod RECORD;
BEGIN
    FOR prod IN QUERY (SELECT id, price FROM products) LOOP
        UPDATE products
        SET price = prod.price * 1.1
        WHERE id = prod.id;
    END LOOP;
END $$;

常见错误以及怎么避免

在LOOP或WHILE里死循环。 如果你忘了加退出条件(EXIT或者WHILE里的正确条件),循环就永远不会停。就像开车没刹车一样。

遍历查询结果时出错。 如果结果数据结构和你预期的不一样,FOR IN QUERY循环里就可能报错。

循环里写了不高效的查询。 比如每次循环都UPDATE,会让执行速度很慢。这种情况最好用一条SQL语句搞定,不要用循环。

2
任务
SQL SELF, 第 51 级, 课程 1
已锁定
使用 `FOR` 循环遍历查询结果
使用 `FOR` 循环遍历查询结果
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION