【问题标题】:Using parameter as column name in Postgres function在 Postgres 函数中使用参数作为列名
【发布时间】:2020-01-22 17:08:31
【问题描述】:

我有一个带有以下表格的 Postgres 表

CREATE TABLE "public"."days" 
(
 "id" integer NOT NULL,
 "day" character varying(9) NOT NULL,
 "visits" bigint[] NOT NULL,
 "passes" bigint[] NOT NULL
);

我想编写一个函数,允许我返回visitspassees 列作为指定id 的结果。我的第一次尝试如下

CREATE OR REPLACE FUNCTION day_entries(INT,TEXT) RETURNS BIGINT[] LANGUAGE sql AS
'SELECT $2 FROM days WHERE id = $1;'

失败并出现类似

的错误

在声明为返回 bigint[] 的函数中返回类型不匹配 DETAIL:实际返回类型为文本。

如果我用visits 代替$2,事情会按预期工作。定义几个函数来匹配days 表中的不同列是没有意义的。有没有办法将实际的列名作为参数传递,同时仍然让 Postgres 满意?

【问题讨论】:

    标签: postgresql function parameters


    【解决方案1】:

    您不能将参数用作标识符(=列名),您需要动态 SQL。这需要 PL/pgSQL:

    CREATE OR REPLACE FUNCTION day_entries(p_id int, p_column text) 
      RETURNS BIGINT[] 
    AS
    $$
    declare 
      l_result bigint[];
    begin
      execute format('SELECT %I FROM days WHERE id = $1', p_column) 
         using p_id
         into l_result;
      return l_result;
    end;     
    $$
    LANGUAGE plpgsql;
    

    format() 在构建动态 SQL 时正确处理标识符。 $1 是一个参数占位符,其值通过execute 语句的using p_id 子句传递。

    【讨论】:

    • 谢谢。 +1 分步说明