所需设置
为了提高某些代码的优雅性,我想知道是否可以做与%ROWTYPE variable from table name相反的事情-从%ROWTYPE
或RECORD
中提取表的名称(最相关的是,在它被传递到接受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.