将FROM中使用的表名自动传递给函数?

时间:2022-08-10 10:08:01

Working with PostgreSQL 9.6.3. I am new to functions in databases.

使用PostgreSQL 9.6.3。我是数据库中的新功能。

Let's say there are multiple tables of item numbers. Each one has the item number, the item cost and several other columns which are factored into the "additional cost". I would like to put the calculation into a function so I can call it for any of these tables.

假设有多个项目编号表。每个都有项目编号,项目成本和其他几个列,这些列被计入“附加成本”中。我想把计算放到一个函数中,所以我可以为任何这些表调用它。

So instead of:

所以代替:

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

I can just do:

我可以这样做:

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

If I want to be able to use it on any of the item tables, I guess I would need to set a table_name parameter that the function takes since adding the table name into the function would be undesirable to say the least.

如果我希望能够在任何项目表上使用它,我想我需要设置一个table_name参数,该函数采用该函数,因为将表名添加到函数中是不可取的。

calc_add_cost(items1)

However, is there a simpler way such that when I call calc_add_cost() it will just use the table name from the FROM clause?

但是,有一种更简单的方法,当我调用calc_add_cost()时,它只会使用FROM子句中的表名吗?

SELECT ....., calc_add_cost(item1) FROM item1

Just seems redundant.

看起来多余。

I did come across a few topics with titles that sounded like they addressed what I was hoping to accomplish, but upon reviewing them it looked like they were a different issue.

我确实遇到过一些主题,其中的标题听起来像是我们希望完成的内容,但在审核它们时,看起来它们是一个不同的问题。

1 个解决方案

#1


2  

You can even emulate a "computed field" or "generated column" like you had in mind. Basics here:

您甚至可以像想象的那样模拟“计算字段”或“生成列”。基础知识:

Simple demo for one table:

一个表的简单演示:

CREATE OR REPLACE FUNCTION add_cost(items1)  -- function name = default col name
  RETURNS numeric AS
$func$
SELECT 
    CASE 
        WHEN $1.labor < 100 AND $1.overhead < .20 THEN numeric '1'
--      WHEN .....
--      WHEN .....
--      WHEN .....
        ELSE numeric '0'  -- ?
    END;
$func$
  LANGUAGE sql IMMUTABLE;

Call:

SELECT *, t.add_cost FROM items1 t;

Note the table-qualification in t.add_cost. I only demonstrate this syntax variant since you have been asking for it. My advise is to use the less confusing standard syntax:

请注意t.add_cost中的table-qualification。我只是证明了这种语法变体,因为你一直在要求它。我的建议是使用较少混淆的标准语法:

SELECT *, add_cost(t) AS add_cost FROM items1 t;  -- column alias is also optional

However, SQL is a strictly typed language. If you define a particular row type as input parameter, it is bound to this particular row type. Passing various whole table types is more sophisticated, but still possible with polymorphic input type.

但是,SQL是一种严格类型的语言。如果将特定行类型定义为输入参数,则它将绑定到此特定行类型。传递各种整个表类型更复杂,但仍然可以使用多态输入类型。

CREATE OR REPLACE FUNCTION add_cost(ANYELEMENT)  -- function name = default col name
  RETURNS numeric AS
$func$
SELECT 
    CASE 
        WHEN $1.labor < 100 AND $1.overhead < .20 THEN numeric '1'
--      WHEN .....
--      WHEN .....
--      WHEN .....
        ELSE numeric '0'  -- ?
    END;
$func$
  LANGUAGE sql IMMUTABLE;

Same call for any table that has the columns labor and overhead with matching data type.

对具有匹配数据类型的列人工和开销的任何表的相同调用。

dbfiddle here

Also see the related simple case passing simple values here:

另请参阅此处传递简单值的相关简单案例:

For even more complex requirements - like also returning various row types - see:

对于更复杂的需求 - 比如返回各种行类型 - 请参阅:

#1


2  

You can even emulate a "computed field" or "generated column" like you had in mind. Basics here:

您甚至可以像想象的那样模拟“计算字段”或“生成列”。基础知识:

Simple demo for one table:

一个表的简单演示:

CREATE OR REPLACE FUNCTION add_cost(items1)  -- function name = default col name
  RETURNS numeric AS
$func$
SELECT 
    CASE 
        WHEN $1.labor < 100 AND $1.overhead < .20 THEN numeric '1'
--      WHEN .....
--      WHEN .....
--      WHEN .....
        ELSE numeric '0'  -- ?
    END;
$func$
  LANGUAGE sql IMMUTABLE;

Call:

SELECT *, t.add_cost FROM items1 t;

Note the table-qualification in t.add_cost. I only demonstrate this syntax variant since you have been asking for it. My advise is to use the less confusing standard syntax:

请注意t.add_cost中的table-qualification。我只是证明了这种语法变体,因为你一直在要求它。我的建议是使用较少混淆的标准语法:

SELECT *, add_cost(t) AS add_cost FROM items1 t;  -- column alias is also optional

However, SQL is a strictly typed language. If you define a particular row type as input parameter, it is bound to this particular row type. Passing various whole table types is more sophisticated, but still possible with polymorphic input type.

但是,SQL是一种严格类型的语言。如果将特定行类型定义为输入参数,则它将绑定到此特定行类型。传递各种整个表类型更复杂,但仍然可以使用多态输入类型。

CREATE OR REPLACE FUNCTION add_cost(ANYELEMENT)  -- function name = default col name
  RETURNS numeric AS
$func$
SELECT 
    CASE 
        WHEN $1.labor < 100 AND $1.overhead < .20 THEN numeric '1'
--      WHEN .....
--      WHEN .....
--      WHEN .....
        ELSE numeric '0'  -- ?
    END;
$func$
  LANGUAGE sql IMMUTABLE;

Same call for any table that has the columns labor and overhead with matching data type.

对具有匹配数据类型的列人工和开销的任何表的相同调用。

dbfiddle here

Also see the related simple case passing simple values here:

另请参阅此处传递简单值的相关简单案例:

For even more complex requirements - like also returning various row types - see:

对于更复杂的需求 - 比如返回各种行类型 - 请参阅: