从任意 %ROWTYPE 或 RECORD 值获取 table-name
Get table-name from an arbitrary %ROWTYPE or RECORD value
所需设置
为了提高某些代码的优雅,我想知道是否was/is可以做与%ROWTYPE variable from table name相反的事情——提取一个table's name from a %ROWTYPE
or 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');
优雅但愚蠢的解决方案
为了允许我在顶部显示呼叫签名,我能想到的最佳解决方案是高开销的猜测和检查方法,这可能是 非常 在生产中使用的坏主意。你可以找到 sqlfiddle here.
plpgsql 级别没有任何解决方案。从理论上讲,您可以在 C 扩展的某些情况下这样做,但代码会非常复杂。 Postgres,PLpgSQL 被设计为静态的,类型严格的环境——动态的 SQL 不会改变太多(设计更喜欢速度,更少的内存使用)。只是不要在 Postgres 中设计过于动态的代码。
有一个简单的解决方案。使用 pg_typeof()
:
CREATE OR REPLACE FUNCTION generic_function(row_data ANYELEMENT)
RETURNS text AS
$func$
DECLARE
table_name text := pg_typeof();
BEGIN
RETURN table_name;
END
$func$ LANGUAGE plpgsql;
显然,这只适用于已注册的复合类型。 每个 table 或视图都属于这一类。但是没有导出tables.
测试:
CREATE TEMP TABLE foo (id int);
SELECT generic_function(NULL::foo);
所需设置
为了提高某些代码的优雅,我想知道是否was/is可以做与%ROWTYPE variable from table name相反的事情——提取一个table's name from a %ROWTYPE
or 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');
优雅但愚蠢的解决方案
为了允许我在顶部显示呼叫签名,我能想到的最佳解决方案是高开销的猜测和检查方法,这可能是 非常 在生产中使用的坏主意。你可以找到 sqlfiddle here.
plpgsql 级别没有任何解决方案。从理论上讲,您可以在 C 扩展的某些情况下这样做,但代码会非常复杂。 Postgres,PLpgSQL 被设计为静态的,类型严格的环境——动态的 SQL 不会改变太多(设计更喜欢速度,更少的内存使用)。只是不要在 Postgres 中设计过于动态的代码。
有一个简单的解决方案。使用 pg_typeof()
:
CREATE OR REPLACE FUNCTION generic_function(row_data ANYELEMENT)
RETURNS text AS
$func$
DECLARE
table_name text := pg_typeof();
BEGIN
RETURN table_name;
END
$func$ LANGUAGE plpgsql;
显然,这只适用于已注册的复合类型。 每个 table 或视图都属于这一类。但是没有导出tables.
测试:
CREATE TEMP TABLE foo (id int);
SELECT generic_function(NULL::foo);