postgresql PL/pgSQL循环产生意外的“范围表条目过多”错误

i2loujxw  于 2023-05-28  发布在  PostgreSQL
关注(0)|答案(1)|浏览(187)

我尝试使用PL/pgsql循环更新一个分区的PostgreSQL表,以限制每次只更新一个分区,因为它包含一个大表上的自连接。我一直得到错误“太多的范围表条目”,我不明白为什么。如果我在WHERE子句中对分区进行硬编码以进行更新,那么即使我使用IN()同时运行10个分区,它也能正常工作。
我还以为他们俩做的是同一件事依次为city_id的每个值循环UPDATE。这样不对吗我怎么才能让它做到这一点?
这不起作用:

DO
$$
DECLARE
    ele record;
BEGIN
    FOR ele IN SELECT city_id 
           FROM dwh.city
    LOOP 
        UPDATE dwh.residence res1
        SET residence_count = res2.residence_count
        FROM (
            SELECT 
                block_id, 
                COUNT(*) as residence_count,
            FROM dwh.residence  
            WHERE 1=1
                AND city_id = ele.city_id
            GROUP BY block_id
        ) res2
        WHERE 1=1
            AND res1.city_id = ele.city_id
            AND res1.block_id = res2.block_id;
    END LOOP;
END;
$$;

但是,这确实有效:

UPDATE dwh.residence res1
SET residence_count = res2.residence_count
FROM (
    SELECT 
        block_id, 
        COUNT(*) as residence_count,
   FROM dwh.residence  
   WHERE 1=1
       AND city_id = 1
  GROUP BY block_id
) res2
WHERE 1=1
    AND res1.city_id = 1
    AND res1.block_id = res2.block_id;
eyh26e7m

eyh26e7m1#

根据@LaurenzAlbe发布的评论,使用动态SQL单独引用表分区解决了错误(我打破了变量,因为我认为这样看起来更清楚):

DO
$$
DECLARE
    var_city_id int;
    var_city_name varchar;
BEGIN
    FOR var_city_id, var_city_name IN 
        SELECT city_id, city_name
        FROM dwh.city
    LOOP 
        EXECUTE
            'UPDATE dwh.residence_' || var_city_name || ' res1
            SET residence_count = res2.residence_count
            FROM (
                SELECT 
                    block_id, 
                    COUNT(*) as residence_count,
                FROM dwh.residence_' || var_city_name || '
                WHERE 1=1
                    AND city_id = ' || var_city_id || '
                GROUP BY block_id
            ) res2
            WHERE 1=1
                AND res1.city_id = ' || var_city_id || '
                AND res1.block_id = res2.block_id;';
    END LOOP;
END;
$$;

相关问题