在 Postgres 函数中使用参数作为列名

Dro*_*dOS 3 postgresql parameters function

我有一个带有以下形式的 Postgres 表

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

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

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

失败并出现以下错误

声明为返回 bigint[] 的函数中返回类型不匹配详细信息:实际返回类型为文本。

如果我把事情放在适当visits的位置,$2就会像预期的那样工作。定义多个函数来匹配表中的不同列是没有意义的days。有没有办法将实际的列名作为参数传递,同时仍然让 Postgres 满意?

小智 10

您不能使用参数作为标识符(=列名称),您需要动态 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;
Run Code Online (Sandbox Code Playgroud)

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