You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

PL/pgSQL中如何定义多列数组变量并返回查询结果

处理PostgreSQL多列数据数组的PL/pgSQL存储过程方案

我懂你这种纠结——单值数组的存储过程写得顺风顺水,一碰到多列数据的数组就卡壳了对吧?问题出在PostgreSQL的数组要求元素是同一种数据类型,而多列数据属于复合类型,不能直接用普通的数值/字符串数组来存储。下面给你两种实用的解决方案,按需选择就行:

方案1:自定义复合类型 + 复合类型数组

如果你需要多次复用这个多列数据结构,先定义一个自定义的复合类型,再用这个类型创建数组变量,步骤如下:

第一步:创建复合类型

先定义和你要存储的多列数据匹配的类型:

CREATE TYPE my_data_row AS (
    id BIGINT,
    name VARCHAR(50),
    amount NUMERIC(10,2)
);

第二步:编写使用复合数组的函数

用这个自定义类型声明数组变量,然后就可以像单列数组一样操作了:

CREATE OR REPLACE FUNCTION testing_multicolumn_array() 
RETURNS TABLE(id BIGINT, name VARCHAR(50), amount NUMERIC(10,2)) 
AS $body$ 
DECLARE 
    l_rows my_data_row[]; -- 声明复合类型数组
BEGIN 
    -- 把多列数据存入数组(注意要把行转成自定义类型)
    l_rows := ARRAY(
        SELECT (1, '商品A', 99.99)::my_data_row 
        UNION ALL
        SELECT (2, '商品B', 159.50)::my_data_row
    );

    -- 这里可以添加你的数据处理逻辑,比如遍历数组修改值
    FOR idx IN 1..array_length(l_rows, 1) LOOP
        l_rows[idx].amount := l_rows[idx].amount * 0.9; -- 打9折
    END LOOP;

    -- 返回处理后的多列数据
    RETURN QUERY SELECT * FROM UNNEST(l_rows);
END; 
$body$ LANGUAGE plpgsql;

方案2:直接使用表变量(无需额外创建类型)

如果只是在当前函数里用一次这个多列结构,直接用TABLE类型的变量会更省事,不需要预先创建自定义类型:

CREATE OR REPLACE FUNCTION testing_multicolumn_table() 
RETURNS TABLE(id BIGINT, name VARCHAR(50), amount NUMERIC(10,2)) 
AS $body$ 
DECLARE 
    -- 直接声明表变量,结构和返回值一致
    l_rows TABLE(id BIGINT, name VARCHAR(50), amount NUMERIC(10,2));
BEGIN 
    -- 把数据插入表变量,就像操作普通表一样
    INSERT INTO l_rows
    SELECT 1, '商品A', 99.99
    UNION ALL
    SELECT 2, '商品B', 159.50;

    -- 处理数据,比如更新表变量中的记录
    UPDATE l_rows SET amount = amount * 0.9;

    -- 返回数据
    RETURN QUERY SELECT * FROM l_rows;
END; 
$body$ LANGUAGE plpgsql;

额外小技巧:复用现有表的结构

如果你要处理的多列数据和已有的某个表结构完全一致,可以直接用%ROWTYPE来声明数组,省去自定义类型的步骤:
比如你有一个products表,结构是id BIGINT, name VARCHAR(50), amount NUMERIC(10,2),那函数里可以这么写:

DECLARE
    l_rows products%ROWTYPE[]; -- 直接复用products表的行类型

这样就可以直接把查询到的products表数据存入这个数组了。

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

火山引擎 最新活动