return 类型的动态列名称

Dynamic column name in return type

我有一个包含多列的 table。我要return详情 table 的调用函数。在下面,我创建了 table 一些记录并且还创建了 return select 结果的函数 声明。

Table:

create table for_test
(
cola varchar(10),
colb varchar(10),
name varchar(20),
address varchar(50)
);

正在插入记录:

insert into for_test values('A101','B101','SAM','Munich');
insert into for_test values('A102','B102','AMC','Belgium');
insert into for_test values('A103','B103','MAM','Shanghai');
insert into for_test values('A104','B104','KOU','Dhaka');

注意:在函数中我传递了一个参数,它被称为p_columnname 我将在 cola or colb 之间传递列名。

如果我传递列名 cola 它必须 return 结果像 cola colb name.

如果我传递列名 colb 它必须 return 结果像 colb cola name.

函数:

create or replace function for_test
(
    p_columnname varchar(20)
)

RETURNS TABLE
(
    _cola varchar(10),
    _colb varchar(10),
    _name varchar(20)
) AS
$$

DECLARE 
    v_details varchar;
    v_query varchar;
BEGIN
    IF p_columnname = 'cola' THEN

        v_details := 'cola,colb,name';

    ELSIF p_columnname = 'colb' THEN

        v_details := 'colb,cola,name';

    ELSE
        v_details := 'cola,colb,name';

    END IF;

    v_query := 'SELECT '|| v_details ||' from for_test';

    RAISE INFO '%',v_query;

    RETURN QUERY EXECUTE v_query;

END;

$$

LANGUAGE PLPGSQL;   

--如果我传递 columnname = 'cola' 这将显示:

SELECT * FROM for_test('cola');

_cola  _colb  _name
------------------- 
 A101   B101   SAM
 A102   B102   AMC
 A103   B103   MAM
 A104   B104   KOU

--如果我传递 columnname = 'colb' 这将显示:

SELECT * FROM for_test('colb');

_cola  _colb  _name
------------------- 
 B101   A101   SAM
 B102   A102   AMC
 B103   A103   MAM
 B104   A104   KOU

问题:如何更改RETURN TABLE TYPE中的列名 如果输入列从 cola 变为 colb?

您可以通过创建 type 来动态更改 return 类型,如下所示

create type colb_a as (colb varchar(10), --_colb comes first
    _cola varchar(10),
    _name varchar(20))

create type cola_b as (cola varchar(10), -- _cola Comes first
    _colb varchar(10),
    _name varchar(20))

TYPE 中,您可以定义调用函数或其他任何内容时应出现的列名称

并以此创建您的函数

create or replace function for_test
(
    _retType anyelement,p_columnname varchar(20)
)

RETURNS  setof anyelement AS


 ...
 ...

LANGUAGE PLPGSQL; 

所以你需要像这样调用函数:

select * from for_test(NULL::cola_b,'cola');

select * from for_test(NULL::colb_a,'colb');