ben*_*trm 10 sql postgresql dblink
我正在使用dblink在数据库之间移动某些数据.一切都是保存和声音,但我想知道是否有更方便的方法来定义dblink查询结果的列定义列表.我可以这样做:
SELECT *
FROM dblink('dbname=remote', 'select * from test')
AS t1(id integer, data text);
Run Code Online (Sandbox Code Playgroud)
我正在与之交互的表在两个数据库(远程和本地)中具有相同的模式定义.我想的是:
SELECT *
FROM dblink('dbname=remote', 'select * from test')
AS t1 LIKE public.test;
Run Code Online (Sandbox Code Playgroud)
要么:
SELECT *
FROM dblink('dbname=remote', 'select * from test')
AS t1::public.test;
Run Code Online (Sandbox Code Playgroud)
列定义列表往往变得很长.有什么我可能忽略的吗?
编辑:
在我创建一个小函数作为解决方法之前,这对我来说是一个问题.
CREATE OR REPLACE FUNCTION dblink_star_func(_conn text, _schema_name text, _table_name text)
RETURNS text
LANGUAGE PLPGSQL
VOLATILE STRICT
AS $function$
DECLARE
_dblink_schema text;
_cols text;
_q text;
_func_name text := format('star_%s', $3);
_func text;
BEGIN
SELECT nspname INTO _dblink_schema
FROM pg_namespace n, pg_extension e
WHERE e.extname = 'dblink' AND e.extnamespace = n.oid;
SELECT array_to_string(array_agg(column_name || ' ' || udt_name), ', ') INTO _cols
FROM information_schema.columns
WHERE table_schema = $2 AND table_name = $3;
_q := format('SELECT * FROM %I.dblink(%L, %L) AS remote (%s)',
_dblink_schema,
_conn,
format('SELECT * FROM %I.%I', $2, $3),
_cols
);
_func := $_func$
CREATE OR REPLACE FUNCTION %s()
RETURNS SETOF %I.%I
LANGUAGE SQL
VOLATILE STRICT
AS $$ %s; $$
$_func$;
EXECUTE format(_func, _func_name, $2, $3, _q);
RETURN _func_name;
END;
$function$;
Run Code Online (Sandbox Code Playgroud)
此函数创建并生成一个包装dblink调用的函数.它肯定不是为了繁重而是方便.如果事实证明它根本不是必要的话会很好.
> select dblink_star_func('dbname=ben', 'public', 'test');
????????????????????
? dblink_star_func ?
????????????????????
? star_test ?
????????????????????
(1 row)
> select * from star_test() where data = 'success';
????????????????
? id ? data ?
????????????????
? 1 ? success ?
????????????????
(1 row)
Run Code Online (Sandbox Code Playgroud)
Rém*_*ron 11
尝试这样的事情:
select (rec).* from dblink('dbname=...','select myalias from foreign_table
myalias') t1 (rec local_type)
Run Code Online (Sandbox Code Playgroud)
示例(从其他数据库获取表统计信息):
select (rec).* from dblink('dbname=foreignDb','select t1 from
pg_stat_all_tables t1') t2 (rec pg_stat_all_tables)
Run Code Online (Sandbox Code Playgroud)
您可能需要确保您的类型始终同步,但这应该有效:
SELECT (t1::test).*
FROM dblink('dbname=remote', 'select * from test') AS t1;
Run Code Online (Sandbox Code Playgroud)
关键是您通常需要括号来确保解析器知道您正在处理元组。
例如这对我有用:
CREATE TABLE test (id int, test bool);
select (t1::test).* from (select 1, true) t1;
Run Code Online (Sandbox Code Playgroud)
但这会引发语法错误:
select t1::test.* from (select 1, true) t1;
Run Code Online (Sandbox Code Playgroud)