【问题标题】:postgres: function with untyped return valuespostgres:具有无类型返回值的函数
【发布时间】:2013-04-24 07:40:43
【问题描述】:

我正在寻找一种方法来定义一个允许返回无类型行值的 postgres 函数。为了论证起见,我们假设存在以下表格:

create table foo(
  id serial primary key,
  value1 varchar(255),
  value2 int,
  value3 datetime,
  value4 boolean
);

我们还有一个函数允许我们返回某些列的结果(这是一个相当人为的示例,但实际上,很多连接发生在内部,我想通过仅使用相关列来最小化):

create or replace function foo_func(col1 text, col2 text) returns 
  table(?, ?) as 
$$
declare 
sql text;
begin
  sql := 'select ' || col1 || ', ' || col2 || ' from foo'
  return execute sql;
end
$$ language plpgsql;

由于列值取决于选定的列参数,因此无法预先定义返回表。有没有办法在不指定它们的值的情况下返回行?我已经考虑返回一个游标,但我不确定这是否是最佳选择。

(可以定义postgresql版本)

【问题讨论】:

    标签: sql postgresql dynamic-sql stored-functions


    【解决方案1】:

    您需要返回setof record (ref)。

    create or replace function foo_func(col1 text, col2 text) returns 
      setof record as 
    $$
    declare 
    sql text;
    r record;
    begin
      sql := 'select ' || col1 || ', ' || col2 || ' from foo';
      for r in execute sql
      loop
        return next r;
      end loop;
      return;
    end
    $$ language plpgsql;
    

    问题是你必须在函数外声明列类型:

    SELECT * from foo_func('value1','value2') as (a varchar(255),b int);
    

    如果声明不匹配,您将收到错误消息:http://sqlfiddle.com/#!12/ce8b0/3

    【讨论】:

    • 与仅选择整个表相比,我没有注意到任何性能损失,这很好。这当然可能是由于 sqlfiddle 缺少样本或不准确造成的。这个返回循环是否已知比 select 慢?
    • @orange sqlfiddle 肯定不是测试的正确位置,因为它只允许非常有限的数据,而且它的性能变化很大。不过,我对循环一无所知。
    • 好的。很诱人,因为它还打印了时间……我会尝试进行更彻底的测试。
    • @orange 如果您使用 psql 运行测试,您可以使用 \timing 打开时间显示。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-27
    • 1970-01-01
    相关资源
    最近更新 更多