代码之家  ›  专栏  ›  技术社区  ›  michal.jakubeczy

PosgreSQL循环语法

  •  0
  • michal.jakubeczy  · 技术社区  · 6 年前

    我有以下循环(简化为示例):

    DO $$
      DECLARE
        l record;
    
      BEGIN
        FOR l IN SELECT id, country_id FROM logo LOOP
          WITH cs AS (
            INSERT INTO logo_settings (targeted) VALUES (true)
            RETURNING id
          )
          INSERT INTO logo_settings_targeted (logo_settings_id, country_id)
          VALUES 
          ( (SELECT id FROM cs),
            logo.country_id,
          );
        END LOOP;
      END;
    END $$;
    

    循环的主体工作良好。但是,如果我把它包装成一个循环(我想为徽标表中的所有记录做记录),它会显示一个错误:

    ERROR: syntax error at or near "END"
      Position: 712
    
    END;
    ^
    

    意思是之前的最后一个EnND END $$; 这对我来说没有多大意义。我不知道该修复什么才能让它运行。有什么提示吗?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Andronicus    6 年前

    有一个 end 对许多人来说。 end loop 关闭循环体:

    DO $$
      DECLARE
        l record;
    
      BEGIN
        FOR l IN SELECT id, country_id FROM logo LOOP
          WITH cs AS (
            INSERT INTO logo_settings (targeted) VALUES (true)
            RETURNING id
          )
          INSERT INTO logo_settings_targeted (logo_settings_id, country_id)
          VALUES 
          ( (SELECT id FROM cs),
            logo.country_id,
          );
        END LOOP;
      END $$;
    
        2
  •  1
  •   S-Man    6 年前

    除了@Andronicus的回答之外,这是一种不使用PL/pgsql的可能方法:

    Click: demo:db<>fiddle

    WITH countries AS  (
        SELECT id, country_id, 
            row_number() OVER ()                                        -- 1
        FROM logo
    ), ins_settings AS (
        INSERT INTO logo_settings(targeted)
        SELECT true FROM countries c
        RETURNING id
    )
    INSERT INTO logo_settings_targeted (logo_settings_id, country_id)
    SELECT
      ins.id, c.country_id
    FROM
      (SELECT id, row_number() OVER () FROM ins_settings) ins            -- 2
    JOIN countries c ON c.row_number = ins.row_number
    
    1. 放第一个 SELECT 将查询(用于循环)转换为顶部的第二个CTE。
    2. 诀窍是,你可以将输出从 logo 选择 声明和第一个插入。您可以使用两个输出具有相同行数的事实。只需在两个输出中添加一列行数。例如,可以使用 row_number() window function 如您所见,对于 标志 选择 我已经在CTE(1)中直接做了这件事,因为 INSERT 输出我在子查询(2)中添加了这一点。现在,两个表上都有相同的标识符,可用于连接。
    3. 连接是第二个的基础 插入 .
    推荐文章