【问题标题】:Postgresql function per row每行的 Postgresql 函数
【发布时间】:2014-10-01 17:10:18
【问题描述】:

我目前正在学习 postgresql 并且有一个菜鸟问题。如果我有一个像这样的简单表格:

CREATE TABLE rectangle
(
    width int,
    length int
);

还有这样的功能:

CREATE OR REPLACE FUNCTION Area()
RETURNS int AS $area$
declare
    area int;
BEGIN
   SELECT (width*length)  into area FROM rectangle;
   return area ;
END;
$area$ LANGUAGE plpgsql;

我这样称呼它:

select width, length, area() from rectangle;

我得到这样的结果:

width  |  length  |  area
-------------------------
2      |     3    |    6
4      |     3    |    6
5      |     2    |    6

这表明 area 函数正在工作,但它只使用表中的第一个条目,而不是相应的行。我究竟做错了什么。提前致谢!

【问题讨论】:

  • 您假设该函数将“知道”它在一行中,因此使用该行。 Not true. 该函数独立于行,您必须将行中的值“传递”到该函数中。虽然这可能只是一个简单的示例,但您不需要为此使用函数,您应该直接在查询中使用 (width*length)
  • 我明白我做错了什么。所以一般来说最好为函数发送pk并添加WHERE
  • 你为什么使用select width,length,(length*width) as area from rectangle >> ??这不是实施 Function 的好情况
  • "一般来说..." mmm, not really, 下面的示例函数都从长度或宽度的任何物理实现中“抽象”了面积计算,因此该函数可用于任何相关情况。如果您基于 PK 的功能,则该功能只能在一种情况下使用。另请注意,在下面的示例函数中,它们不需要使用select,因为您传递了已经选择的长度和宽度。传递一个 pk 需要另一个选择,这不是很好。

标签: sql function postgresql parameters


【解决方案1】:
CREATE OR REPLACE FUNCTION Area(integer, integer)
RETURNS int AS $area$
declare
    area int;
BEGIN
   SELECT ($1 * $2)  into area ;
   return area ;
END;
$area$ LANGUAGE plpgsql;

然后在您的查询中:

select width, length, area(width, length) from rectangle;

【讨论】:

    【解决方案2】:

    在您的函数中,您从表中的一个未确定行中获取值。需要将参数传递给函数

    create or replace function area (
        width int, length int
    ) returns int as $area$
    
       select width * length;
    
    $area$ language sql;
    

    可以是纯 SQL。

    【讨论】:

      【解决方案3】:

      这样效率更高:

      CREATE OR REPLACE FUNCTION Area(integer, integer)
      RETURNS int AS 
      $body$
      BEGIN
         return ($1 * $2) ;
      END;
      $body$ 
      LANGUAGE plpgsql 
      IMMUTABLE;
      

      原因:

      • 没有 SQL 评估;
      • IMMUTABLE 函数不能修改数据库,并且保证在给定相同参数的情况下永远返回相同的结果。此类别允许优化器在查询使用常量参数调用该函数时预先评估该函数。例如,像 SELECT ... WHERE x = 2 + 2 这样的查询可以简化为 SELECT ... WHERE x = 4,因为整数加法运算符的底层函数标记为 IMMUTABLE。 (见more)。

      【讨论】:

        猜你喜欢
        • 2019-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多