使用变量而不是显式列名访问列

Access column using variable instead of explicit column name

我想使用变量而不是静态列名来访问列。
示例:

variable := 'customer';

SELECT table.variable (this is what I would prefer) instead of table.customer

我需要此功能,因为我的 table 中的记录在数据长度方面有所不同(例如,有些数据有 10 列,有些有 14 或 16 列等),因此我需要动态寻址列.据我了解,我不能通过索引来寻址列(例如 select table 的第 8 列)对吗?

我可以循环并将所需的列名称放入给定迭代的变量中。但是,当我尝试使用该变量访问列时出现错误(例如 table_name.variable 不工作)。

为了简单起见,我只粘贴了一些虚拟代码来说明问题:

CREATE OR REPLACE FUNCTION dynamic_column_name() returns text
LANGUAGE PLPGSQL
AS $$
DECLARE
col_name text;
return_value text;

BEGIN

create table customer (
    id bigint,
    name varchar
);

INSERT INTO customer VALUES(1, 'Adam');

col_name := 'name';

-- SELECT customer.name INTO return_value FROM customer WHERE id = 1; -- WORKING, returns 'Adam' but it is not DYNAMIC.
-- SELECT customer.col_name INTO return_value FROM customer WHERE id = 1; -- ERROR:  column customer.col_name does not exist
-- SELECT 'customer.'||col_name INTO return_value FROM customer WHERE id = 1; -- NOT working, returns 'customer.name'
-- SELECT customer||'.'||col_name INTO return_value FROM customer WHERE id = 1; -- NOT working, returns whole record + .name, i.e.: (1,Adam).name

DROP TABLE customer;
RETURN return_value;
END;
$$;

SELECT dynamic_column_name();

那么如何在寻址customertable列时使用col_name变量通过SQL查询获取'Adam'字符串?

SQL 不允许参数化标识符(包括列名)或语法元素。只有可以作为参数。

为此你需要动态 SQL。 (基本上,构建 SQL 字符串并执行。)在 plpgsql 函数中使用 EXECUTE。有多种语法变体。对于您的简单示例:

CREATE OR REPLACE FUNCTION dynamic_column_name(_col_name text, OUT return_value text)
  RETURNS text
  LANGUAGE plpgsql AS
$func$
BEGIN
   EXECUTE format('SELECT %I FROM customer WHERE id = 1', _col_name)
   INTO return_value;
END
$func$;

致电:

SELECT dynamic_column_name('name');

db<>fiddle here

当然,数据类型必须兼容。

更多示例: