我发现这篇非常有趣的文章:Refactor a PL/pgSQL function to return the output of various SELECT queries 来自Erwin Brandstetter的内容,它描述了如何仅使用一个函数即可返回各种表的所有列:
CREATE OR REPLACE FUNCTION data_of(_table_name anyelement, _where_part text)
RETURNS SETOF anyelement AS
$func$
BEGIN
RETURN QUERY EXECUTE
'SELECT * FROM ' || pg_typeof(_table_name)::text || ' WHERE ' || _where_part;
END
$func$ LANGUAGE plpgsql;
致电:
SELECT * FROM data_of(NULL::tablename,'1=1 LIMIT 1');
这很好。我需要一个非常相似的解决方案,但要通过dblink从不同数据库上的表中获取数据。这意味着调用NULL::tablename
将失败,因为在进行调用的数据库上该表不存在。我不知道如何使这项工作。通过dblink在函数内部连接到其他数据库的任何尝试均无法获得NULL :: tablename的结果。似乎polymorph函数需要一个polymorph参数来创建隐式函数的返回类型。
如果有人能帮助我,我将非常感激。
非常感谢
亲切的问候 布莱恩
答案 0 :(得分:0)
似乎这个要求比我想象的要难解释。这是第二次尝试测试设置:
数据库1
首先,我们创建一个测试表,其中包含有关数据库1的一些数据:
CREATE TABLE db1_test
(
id integer NOT NULL,
txt text
)
WITH (
OIDS=TRUE
);
INSERT INTO db1_test (id, txt) VALUES(1,'one');
INSERT INTO db1_test (id, txt) VALUES(2,'two');
INSERT INTO db1_test (id, txt) VALUES(3,'three');
现在,我们在数据库1上创建多态函数:
-- create a polymorph function with a polymorph parameter "_table_name" on database 1
-- the return type is set implicit by calling the function "data_of" with the parameter "NULL::[tablename]" and a where part
CREATE OR REPLACE FUNCTION data_of(_table_name anyelement, _where_part text)
RETURNS SETOF anyelement AS
$func$
BEGIN
RETURN QUERY EXECUTE
'SELECT * FROM ' || pg_typeof(_table_name)::text || ' WHERE ' || _where_part;
END
$func$ LANGUAGE plpgsql;
现在,如果一切都按数据库1的方式工作,我们将进行测试调用
SELECT * FROM data_of(NULL::db1_test, 'id=2');
有效。请注意,我没有指定表db1_test的任何列。现在我们切换到数据库2。
数据库2
这里,我需要从数据库1完全调用以前的 data_of ,尽管 WITHOUT 在调用时就知道所选表的列。不幸的是,这是行不通的,唯一起作用的呼叫是这样的:
SELECT
*
FROM dblink('dbname=[database1] port=[port] user=[user] password=[password]'::text, 'SELECT * FROM data_of(NULL::db1_test, \'id=2\')'::text)
t1(id integer, txt text);
结论
此调用有效,但是如您所见,我需要至少一次指定我要选择的表中所有列的外观。我正在寻找任何绕过此方法的方法,并且可以在不知道数据库1表中的所有列的情况下进行调用。
最终目标
我的最终目标是在数据库2中创建一个类似于
的函数SELECT * from data_of_dblink('table_name','where_part')
,它在database1上调用internaly data_of(),从而可以选择其中where部分为参数的其他数据库上的表。它应该像静态视图一样工作,但是可以将where部分作为参数传递。
我非常愿意提出建议。
非常感谢
布莱恩