【问题标题】:Get table-name from an arbitrary %ROWTYPE or RECORD value从任意 %ROWTYPE 或 RECORD 值获取表名
【发布时间】:2016-03-15 09:46:12
【问题描述】:

所需的设置

为了提高一些代码的优雅,我想知道是否/是否可以与%ROWTYPE variable from table name 做相反的事情——中提取一个表的名称> 一个%ROWTYPERECORD(最相关的是,在它被传递到一个接受ANYELEMENT 伪类型的函数之后):

CREATE OR REPLACE FUNCTION generic_function(row_data ANYELEMENT)
RETURNS INT AS $$
DECLARE
    table_name TEXT = get_table_name(row_data);
BEGIN
    -- [ work goes here ]
END;
$$ LANGUAGE plpgsql;

当前的解决方法

CREATE OR REPLACE FUNCTION generic_function(row_data ANYELEMENT, table_name TEXT) 
RETURNS INT AS $$
BEGIN
    -- [ work goes here ]
END;
$$ LANGUAGE plpgsql;

如果你能想象它在调用代码中的样子,那么这个解决方法感觉有点多余:

SELECT INTO x * FROM mytable WHERE foo = bar; 
PERFORM generic_function(x,'mytable');

优雅但愚蠢的解决方案

为了让我在顶部显示呼叫签名,我能想到的最佳解决方案是一种高开销的猜测和检查方法,这可能是一个非常糟糕的主意在生产中使用。你可以找到sqlfiddlehere

【问题讨论】:

    标签: sql postgresql function plpgsql


    【解决方案1】:

    有一个简单的解决方案。使用pg_typeof()

    CREATE OR REPLACE FUNCTION generic_function(row_data ANYELEMENT)
      RETURNS text AS
    $func$
    DECLARE
       table_name text := pg_typeof($1);
    BEGIN
       RETURN table_name;
    END
    $func$ LANGUAGE plpgsql;
    

    显然,这仅适用于已注册的复合类型。 每个表或视图都属于这一类。但不是派生表。

    测试:

    CREATE TEMP TABLE foo (id int);
    SELECT generic_function(NULL::foo);
    

    Here is a search for related answers.

    【讨论】:

      【解决方案2】:

      在 plpgsql 级别上没有任何解决方案。从理论上讲,您可以在 C 扩展中的某些情况下做到这一点,但代码会非常复杂。 Postgres、PLpgSQL 被设计为静态的、类型严格的环境——动态 SQL 并没有对其进行太多改变(设计更喜欢速度,更少的内存使用)。只是不要在 Postgres 中设计过于动态的代码。

      【讨论】:

      • 我忘记了,是的 - 但对于重要的查询,它应该不起作用。
      猜你喜欢
      • 2020-10-02
      • 2016-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多