所需设置
为了提高某些代码的优雅性,我想知道是否可以做与%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

最佳答案

有一个简单的解决办法。使用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.

09-15 17:29