You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL中如何在数组/变量中存储多列数据并循环遍历

实现方法

你当前的写法有3个核心问题需要修正:

  • 变量类型定义错误:你声明的unsatified_documents driver_expiring_documents;是单行复合类型变量,无法存储多行查询结果,也不支持数组遍历语法,需要声明为该复合类型的数组
  • 查询字段顺序和复合类型定义不匹配:自定义类型driver_expiring_documents的字段顺序是driver_id在前、expiration_date在后,但原查询先查expiration_date再查driver_id,会导致字段值错位
  • 数组非空判断写法不规范:直接和'{}'比较在部分场景下会出现判断异常,建议用数组基数判断更可靠

完整实现代码

你可以直接在PL/pgSQL函数、存储过程或匿名块中使用如下写法:

declare
    -- 注意变量类型是复合类型的数组,用于存储多行结果
    unsatified_documents driver_expiring_documents[];
    expiring_doc driver_expiring_documents;
    driver_id_arg text;
    expiring_date date;
begin
    -- 将查询结果聚合为数组存入变量,调整字段顺序和复合类型结构对齐
    select array_agg(
        (driver_id, expiration_date)::driver_expiring_documents
    )
    into unsatified_documents
    from (
        select expiration_date, driver_id from all_requirements_driver_documents 
        where expiration_date <= (now() + interval '1 month')::date 
          and expiration_date > (now() - interval '7 day')::date
        union
        select expiration_date, driver_id from all_requirements_vehicle_documents 
        where expiration_date <= (now() + interval '1 month')::date 
          and expiration_date > (now() - interval '7 day')::date
    ) t;

    -- 判断数组非空后遍历
    if cardinality(unsatified_documents) > 0 then
        foreach expiring_doc in array unsatified_documents loop
            -- 提取字段值
            driver_id_arg := expiring_doc.driver_id;
            expiring_date := expiring_doc.expiration_date;
            
            -- 在此处编写后续业务逻辑即可
        end loop;
    end if;
end;

更简洁的替代方案

如果你不需要把结果集暂存做二次复用,完全不需要定义数组变量,直接用游标循环遍历查询结果即可,性能更好、代码更简洁:

declare
    driver_id_arg text;
    expiring_date date;
begin
    for expiring_doc in (
        select expiration_date, driver_id from all_requirements_driver_documents 
        where expiration_date <= (now() + interval '1 month')::date 
          and expiration_date > (now() - interval '7 day')::date
        union
        select expiration_date, driver_id from all_requirements_vehicle_documents 
        where expiration_date <= (now() + interval '1 month')::date 
          and expiration_date > (now() - interval '7 day')::date
    ) loop
        driver_id_arg := expiring_doc.driver_id;
        expiring_date := expiring_doc.expiration_date;
        -- 在此处编写后续业务逻辑即可
    end loop;
end;

关键语法说明

  • array_agg()会将查询返回的多行结果聚合成一个数组,每个数组元素对应一行数据,强制类型转换保证结构和自定义复合类型完全匹配
  • cardinality()返回数组的元素总个数,值大于0即代表数组非空,兼容性比直接和空数组字面量比较更好

内容的提问来源于stack exchange,提问作者Alwaysblue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 13:45:34