【问题标题】:How to put part of a SELECT statement into a Postgres function如何将 SELECT 语句的一部分放入 Postgres 函数
【发布时间】:2018-02-20 06:00:59
【问题描述】:

我有一个SELECT 语句的一部分,它是一组相当长的条件语句。我想把它放到一个函数中,这样我就可以在需要使用它的任何表上更有效地调用它。

所以而不是:

SELECT 
    itemnumber, 
    itemname, 
    base, 
    CASE 
        WHEN labor < 100 AND overhead < .20 THEN
        WHEN .....
        WHEN .....
        WHEN .....
        .....
    END AS add_cost,
    gpm
FROM items1;

我只能这样做:

SELECT 
    itemnumber, 
    itemname, 
    base, 
    calc_add_cost(),
    gpm
FROM items1;

是否可以将SELECT 的一部分添加到函数中,以便仅通过调用函数来注入?

我正在对文档和 Google 进行分类,如果使用 plpgsql 语言而不是 sql 语言创建函数似乎是可能的。但是,我正在阅读的内容不是很清楚。

【问题讨论】:

  • case 语句需要一个存储过程。只需谷歌它,您的问题就会得到解决。
  • @AnkitBajpai:Postgres 中没有真正的“存储过程”。只是功能,几乎但不完全相同。 (我们需要的只是一个函数。)
  • 顺便说一句,您刚刚结束了您的相关问题 (stackoverflow.com/questions/46164931/…) - 一种使用可变表类型作为输入的方法 - 并使其看起来像生成的列。如果您仍然需要此问题,请重新打开其他问题。
  • 谢谢!我认为您在下面的回答有助于回答这个问题,但我绝对愿意提供任何其他信息。
  • @ErwinBrandstetter,感谢您纠正 m。我从来不知道 PostGres 从不支持过程。

标签: sql database postgresql function plpgsql


【解决方案1】:

您不能只将SELECT 语句的任何 部分包装到函数中。但是像 CASE 这样的表达式可以很容易地被包装:

CREATE OR REPLACE FUNCTION  pg_temp.calc_add_cost(_labor integer, _overhead numeric)
  RETURNS numeric AS
$func$
SELECT 
    CASE 
        WHEN _labor < 100 AND _overhead < .20 THEN numeric '1'  -- example value
--      WHEN .....
--      WHEN .....
--      WHEN .....
        ELSE numeric '0'  -- example value
    END;
$func$
  LANGUAGE sql IMMUTABLE;

虽然您可以为此也使用 PL/pgSQL,但演示是一个简单的 SQL 函数。见:

根据您的需要调整输入和输出数据类型。只是猜测integernumeric 缺乏信息。

呼叫:

SELECT calc_add_cost(1, 0.1);

在你的声明中:

SELECT 
    itemnumber, 
    itemname, 
    base, 
    calc_add_cost(labor, overhead) AS add_cost,  -- pass column values as input
    gpm
FROM items1;

您应该了解一些有关 Postgres 函数的基础知识才能正确使用。可能从 CREATE FUNCTION 上的手册页开始。

这里还有许多相关的问题和答案。

另请参阅此处传递整行的相关、更复杂的案例:

【讨论】:

  • 如果他需要表格中的一堆列怎么办。您将如何将整行传递给函数?
  • @Andreas:你可以通过一整行。语法为 SELECT calc_add_cost(t) FROM mytable t; 请参阅:stackoverflow.com/questions/31148157/… 但由于 OP 想要使用函数 on any table I need to use it on,将函数绑定到特定行类型作为输入是不明智的。也有复合类型。一切可能,这取决于具体的用例。
  • 嘿,谢谢!这对我入门有很大帮助,并帮助回答了我今天发布的另一个问题。关于传递一整行,这个表有大约 50 列,其中可能有 8 列将传递给这个函数。在什么时候通过整行才有意义?而且,听起来如果我传递整行,我不必指定要作为参数传递给函数的列,但我可以在函数内指定这些列?换句话说,传递行可以让我在调用函数时访问列而不指定它们?
  • @Andreas:不过,第二个,我们可以使这项工作适用于具有多态输入的可变表类型。也很优雅。我在这里为 sockpuppet 的另一个问题添加了一个演示:stackoverflow.com/q/46164931/939860
  • @sockpuppet:是的,通过整行可以访问该行的所有列。但是您需要提前知道列名才能访问函数体中的各个列。好吧,也可能有一些方法可以解决这个问题,比如转换为 JSON ......但也有陷阱。
猜你喜欢
  • 2016-09-01
  • 2017-02-14
  • 1970-01-01
  • 1970-01-01
  • 2022-12-18
  • 1970-01-01
  • 1970-01-01
  • 2021-06-27
  • 2014-02-11
相关资源
最近更新 更多