【问题标题】:Passing a ResultSet into a Postgresql Function将 ResultSet 传递给 Postgresql 函数
【发布时间】:2013-08-15 17:06:02
【问题描述】:

是否可以将 postgres 查询的结果作为输入传递给另一个函数?

作为一个非常人为的例子,假设我有一个类似的查询

SELECT id, name
FROM users
LIMIT 50

我想创建一个函数my_function,它接受第一个查询的结果集并返回最小ID。这在 pl/pgsql 中可能吗?

SELECT my_function(SELECT id, name FROM Users LIMIT 50); --returns 50

【问题讨论】:

    标签: sql postgresql plpgsql postgresql-9.2


    【解决方案1】:

    您可以使用 光标,但这对于计算最小值非常不切实际。

    我会为此目的使用一个临时表,并传递表名以在动态SQL中使用:

    CREATE OR REPLACE FUNCTION f_min_id(_tbl regclass, OUT min_id int) AS 
    $func$
    BEGIN
    
    EXECUTE 'SELECT min(id) FROM ' || _tbl
    INTO min_id;
    
    END  
    $func$ LANGUAGE plpgsql;
    

    呼叫:

    CREATE TEMP TABLE foo ON COMMIT DROP AS
    SELECT id, name
    FROM   users
    LIMIT  50;
    
    SELECT f_min_id('foo');
    

    要点

    -> SQLfiddle demo

    【讨论】:

      【解决方案2】:

      我会在另一方面解决问题,为结果集的每条记录调用aggregate function。它没有那么灵活,但可以为您提供工作提示。

      作为遵循您的示例问题的示例:

      CREATE OR REPLACE FUNCTION myMin ( int,int ) RETURNS int AS $$
        SELECT CASE WHEN $1 < $2 THEN $1 ELSE $2 END;
      $$ LANGUAGE SQL STRICT IMMUTABLE;
      
      CREATE AGGREGATE my_function ( int ) (
          SFUNC = myMin, STYPE = int, INITCOND = 2147483647 --maxint
      );
      
      SELECT my_function(id) from (SELECT * FROM Users LIMIT 50) x; 
      

      【讨论】:

      • 明确一点,在 min 的简单情况下,您的函数/聚合定义不是必需的,对吧?我相信你会从SELECT min(id) from (SELECT * FROM Users LIMIT 50) x 得到同样的效果。因此,您的答案没有回答一般问题,而是说明了如何定义任意聚合函数并将其应用于结果集。如果我误解了,请告诉我。
      • @Sigfried 是的,问题只是一个理论样本。
      【解决方案3】:

      不可能将一个泛型类型 RECORD 的数组传递给一个 plpgsql 函数,这实际上是您想要做的。

      您可以做的是传入特定用户定义的TYPE 或特定表行类型的数组。在下面的示例中,您还可以将参数数据类型换成表名 users[](尽管这显然意味着获取 users 表行中的所有数据)。

      CREATE TYPE trivial {
      "ID" integer,
      "NAME" text
      }
      
      CREATE OR REPLACE FUNCTION trivial_func(data trivial[])
        RETURNS integer AS
      $BODY$
      DECLARE 
      
      BEGIN
          --Implementation here using data
          return 1;
      
      END$BODY$
        LANGUAGE 'plpgsql' VOLATILE;
      

      【讨论】:

      • CREATE TYPE 命令在 PostgreSQL 版本 9.4.4 上因语法错误而失败。
      • 感谢@AdamMackler - 在 9+ 中创建类型琐碎的 AS { }
      • 你能提供一个调用这个函数的例子吗?
      【解决方案4】:

      我认为没有办法将记录集或表传递给函数(但如果我错了,我会很高兴)。我最好的建议是传递数组:

      create or replace function my_function(data int[])
      returns int
      as
      $$
         select min(x) from unnest(data) as x
      $$
      language SQL;
      

      sql fiddle demo

      【讨论】:

        猜你喜欢
        • 2019-06-22
        • 2019-04-01
        • 2013-06-12
        • 1970-01-01
        • 1970-01-01
        • 2010-12-16
        • 2015-01-18
        • 1970-01-01
        • 2014-07-16
        相关资源
        最近更新 更多