PostgreSQL-分页批量复制表-for循环
另有 大表分页提交update见《PostgreSQL-慢sql查询优化过程-大SQL文件分割-大表分页提交update结果》
DO $$
DECLARE
i integer;
page_size integer = 1000;
total_count integer;
total_page integer;
total_count_bak bigint;
BEGIN
SELECT COUNT(*) INTO total_count FROM bos_data_flag_info;
total_page = total_count / page_size;
IF total_count % 10 > 0 THEN
total_page = total_page + 1;
END IF;
RAISE NOTICE '共有 % 页,每页 % 条,共有 % 条,', total_page, page_size ,total_count;
FOR pageNum IN 1..total_page LOOP
RAISE NOTICE '执行第: % 页', pageNum;
INSERT INTO bos_data_flag_info_bak SELECT * FROM bos_data_flag_info i
-- WHERE NOT EXISTS ( -- 有问题,会导致漏数据
-- SELECT 1 FROM bos_data_flag_info_bak b WHERE b.id = i.id )
ORDER BY ID ASC LIMIT page_size OFFSET (pageNum - 1) * (page_size) ;
-- COMMIT非常关键,不然整个for循环就是1个大事务
-- COMMIT非常关键,不然整个for循环就是1个大事务
-- COMMIT非常关键,不然整个for循环就是1个大事务
COMMIT;
END LOOP;
-- 开始校验总数
SELECT COUNT(*) INTO total_count_bak FROM bos_data_flag_info_bak;
IF total_count_bak = total_count THEN
RAISE NOTICE '数据条数一致,新老表均有 % 条', total_count_bak ;
ELSE
RAISE NOTICE '数据条数不一致';
END IF;
END;
$$ LANGUAGE plpgsql;
以下来自AI:
PostgreSQL 通过其内置的过程语言 PL/pgSQL 支持 FOR 循环。PL/pgSQL 提供了两种类型的 FOR 循环:一种是基于数值范围的循环,另一种是基于查询结果集的循环。
基于数值范围的循环
这种循环类似于其他编程语言中的 for 循环,它会在一个数值范围内迭代。例如:
DO $$
DECLARE
i integer;
BEGIN
FOR i IN 1..10 LOOP
RAISE NOTICE 'The number is: %', i;
END LOOP;
END;
$$ LANGUAGE plpgsql;
基于查询结果集的循环
这种循环会迭代查询结果中的每一行。在每次迭代中,循环变量(通常是一个记录类型)会被设置为结果集中下一行的值。例如:
DO $$
DECLARE
rec record;
BEGIN
FOR rec IN SELECT * FROM some_table LOOP
RAISE NOTICE 'Processing row with id: %', rec.id;
END LOOP;
END;
$$ LANGUAGE plpgsql;
在这个例子中,some_table 是你要迭代的表的名称。rec 是一个记录类型变量,它在每次循环中都会被设置为 SELECT 语句返回的下一行的值。
使用 FOR 循环进行数据处理
FOR 循环可以用于各种数据处理任务,包括但不限于:
分批处理数据
动态生成 SQL 语句
执行重复性的数据库操作
示例:分批更新数据
如果你想分批更新一个大表,可以使用 FOR 循环结合 LIMIT 和 OFFSET 来实现:
DO $$
DECLARE
batch_size integer := 1000;
offset integer := 0;
BEGIN
FOR i IN 1..(SELECT CEIL(COUNT(*)::float / batch_size FROM your_table)) LOOP
UPDATE your_table SET column_to_update = new_value
WHERE ctid IN (SELECT ctid FROM your_table ORDER BY id LIMIT batch_size OFFSET offset);
offset := offset + batch_size;
END LOOP;
END;
$$ LANGUAGE plpgsql;
在这个例子中,your_table 是你要更新的表的名称,column_to_update 是你想要更新的列的名称,new_value 是新的值,ctid 是一个特殊系统列,用于标识行的物理位置,id 是用于排序的列,以确保每次都能选择不同的行。
请注意,虽然 FOR 循环在 PL/pgSQL 中是一个强大的工具,但你应该谨慎使用,特别是对于大规模数据操作,因为不当使用可能会导致性能问题或锁定问题。在处理大量数据时,考虑使用批处理、并行处理或其他优化策略。
正文到此结束
- 本文标签: PostgreSQL PSQL PgSQL
- 本文链接: https://code.jiangjiesheng.cn/article/347
- 版权声明: 本文由小江同学原创发布,转载请先联系本站长,谢谢。