【问题标题】:Access column using variable instead of explicit column name使用变量而不是显式列名访问列
【发布时间】:2021-05-13 01:38:36
【问题描述】:

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

variable := 'customer';

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

我需要这个功能,因为我的表中的记录在数据长度方面有所不同(例如,有些数据在 10 列中,有些在 14 或 16 列等),所以我需要动态处理列。据我了解,我不能通过索引来处理列(例如,选择表格的第 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();

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

【问题讨论】:

    标签: postgresql plpgsql dynamic-sql


    【解决方案1】:

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

    为此,您需要动态 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小提琴here

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

    更多示例:

    【讨论】:

    • 非常感谢 Erwin Brandstetter!执行和格式化使我能够解决我的真实案例问题。我想知道我是否可以将其应用于 CURSOR? IE。我想遍历每一行(记录)并用它的值做一些事情。但是我仍然需要使用变量(例如 cursor.variable 而不是 cursor.name)访问列。我设法通过使用后续 ID 遍历表来完成任务,并且每次迭代都通过使用该 ID 搜索来选择所需的值 - 这是低效的。我无法使用 Cursor 实现这一目标,这可以让我每次迭代都通过 ID 进行搜索
    • @jans:您可能会问另一个 question,其中包含有关该光标事物的所有相关详细信息。
    猜你喜欢
    • 1970-01-01
    • 2013-12-07
    • 2017-10-24
    • 1970-01-01
    • 2011-12-16
    • 2022-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多