【问题标题】:Return a query from a function?从函数返回查询?
【发布时间】:2018-06-14 22:36:56
【问题描述】:

我正在使用 PostgreSQL 8.4,我想创建一个函数来返回包含多行的查询。
以下函数不起作用

create function get_names(varchar) returns setof record AS $$
declare
    tname alias for $1;
    res setof record;
begin
    select * into res from mytable where name = tname;
    return res;
end;
$$ LANGUAGE plpgsql;

record 类型只允许单行。

如何返回整个查询?我想使用函数作为查询模板。

【问题讨论】:

  • 一如既往,PostgreSQL 的版本号会有所帮助。 :)
  • 谢谢,效果很好。
  • 请注意,尽管在美学上令人愉悦,但行集函数在现实生活中往往表现不佳。关键是它们不会被查询优化器“分解”。像“从不存在的 f() 中选择 (select ... from f())”这样的简单查询可以导致两个两个,甚至三个排序步骤。小心使用。
  • @wildplasser:虽然可以在您实际嵌套表函数时发生,但只要您不这样做,它们确实执行得非常快。实际上比查询本身更快,因为查询计划可以被缓存。
  • @Erwin Brandstetter:是也不是。作为单身人士执行,他们可以为您节省编译和规划成本;与其他“真实”查询元素结合使用时,它们可能是灾难性的,导致过多的可避免的扫描和排序步骤。

标签: sql function postgresql plpgsql


【解决方案1】:
CREATE OR REPLACE FUNCTION get_names(_tname varchar)
  RETURNS TABLE (col_a integer, col_b text) AS
$func$
BEGIN
   RETURN QUERY
   SELECT t.col_a, t.col_b  -- must match RETURNS TABLE
   FROM   mytable t
   WHERE  t.name = _tname;    
END
$func$  LANGUAGE plpgsql;

这样调用:

SELECT * FROM get_names('name')

要点:

  • 使用RETURNS TABLE,因此您不必在每次调用时都提供列名列表。

  • 使用RETURN QUERY,简单多了。

  • 对列名进行表限定以避免与同名的OUT 参数(包括使用RETURNS TABLE 声明的列)发生命名冲突。

  • 使用命名变量而不是 ALIAS。更简单,做同样的事情,这是首选方式。

  • 这样的简单函数也可以写成LANGUAGE sql

CREATE OR REPLACE FUNCTION get_names(_tname varchar)
  RETURNS TABLE (col_a integer, col_b text) AS
$func$
SELECT t.col_a, t.col_b  --, more columns - must match RETURNS above
FROM   mytable t
WHERE  t.name = $1;
$func$ LANGUAGE sql;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-22
    • 2018-05-26
    • 1970-01-01
    • 2012-04-27
    • 1970-01-01
    • 2017-01-13
    • 2016-06-10
    • 2016-01-12
    相关资源
    最近更新 更多