PostgreSQL的dblink扩展模块使用方法

PostgreSQL想要在A库下查询B库的表,可以使用dblink插件。PostgreSQL的dblink是一个支持在一个数据库会话中连接到其他PostgreSQL数据库的扩展模块,可以实现在不同的数据库之间进行通信和交互。

它可以让你在一个数据库中访问另一个数据库的表和函数,甚至可以在不同的服务器之间进行数据交互。

pgsql9.6版本以后自带,不需要手动安装,另外PG使用dblink执行一个远程查询时,必须在调用时定义返回的列名和类型。

dblink用法

创建 pg dblink扩展

复制代码
CREATE EXTENSION IF NOT EXISTS dblink;
###如果已经有,可以在 pg 扩展表查到
SELECT * FROM pg_extension WHERE extname = 'dblink'; 
或使用\dx 
postgres=# \dx
                                                 已安装扩展列表
        名称        | 版本 |  架构模式  |                                  描述
--------------------+------+------------+------------------------------------------------------------------------
 adminpack          | 2.1  | pg_catalog | administrative functions for PostgreSQL
 dblink             | 1.2  | postgres   | connect to other PostgreSQL databases from within a database
 oracle_fdw         | 1.2  | postgres   | foreign data wrapper for Oracle access
 pg_stat_statements | 1.9  | postgres   | track planning and execution statistics of all SQL statements executed
 plpgsql            | 1.0  | pg_catalog | PL/pgSQL procedural language

建立远程连接

复制代码
SELECT dblink_connect('local_connect','hostaddr=127.0.0.1 port=5432 dbname=xxxx user=xxxx password=xxxx') as dev;
解释:
'local_connect'  是我自定义的连接的名称
hostaddr=127.0.0.1  表示是本机地址
port=5432  表示使用5432端口,自行设置
dbname  表示要访问的数据库的名称
user,password分别表示用户名和密码,根据自己配置的用户名密码更改

如:
postgres=# SELECT dblink_connect('local_connect','hostaddr=127.0.0.1 port=5432 dbname=hrdb user=hr password=hr') as dev;

 dev
-----

 OK
(1 行记录)

-- 查询所有已链接的dblink
select dblink_get_connections();

PS:

当dblink连接的是同一个PG实例下的不同数据库时,hostaddr就写 127.0.0.1,不用写实际的实例地址。

当是不同实例时,需要写正确的实例,且这两个实例地址间网络是通的。

复制代码
postgres=# select dblink_get_connections();
 dblink_get_connections
------------------------
 {local_connect}
(1 行记录)

执行查询

复制代码
--跨库查询
SELECT num,id FROM dblink('local_connect','select num,id from hr.demotable') as t(num numeric,id integer);
SELECT * FROM dblink('local_connect','select num,id from hr.demotable') as t(num numeric,id integer);
SELECT * FROM dblink('local_connect','select * from hr.demotable') as t(num numeric,id integer);

--跨库查询写入
insert into t_dblink
select * from dblink('hostaddr=127.0.0.1 port=5432 dbname=hrdb user=hr password=hr','select * from hr.demotable where id<1000') as t(num numeric,id integer);

####使用 dblink 函数从远程数据库获取数据。 local_connect是预先配置好的远程数据库连接名
####dblink 中查询语句被引号括起来,如果查询语句本身有引号,需要多写一个引号做转义
####AS t()表示dblink返回的结果集定义了一个别名't',并指定了每个列的数据类型

关闭连接

复制代码
-- 关闭远程连接
###在PostgreSQL中dblink是会话级别;会话断开即dblink也关闭。当然也可以在会话中手动关闭
SELECT dblink_disconnect('local_connect');

-- 查询所有已链接的dblink
select dblink_get_connections();

简便写法

上面使用方法比较繁琐,要先创建 dblink连接才能使用,也可以写成下面这种方式,在一个语句中完成:

复制代码
--直接写 dblink 方式,预先配置好的到远程数据库的连接名 
SELECT * FROM dblink('hostaddr=127.0.0.1 port=5432 dbname=hrdb user=hr password=hr','select * from hr.demotable') as t(num numeric,id integer);


create table t_dblink as select * from dblink('hostaddr=127.0.0.1 port=5432 dbname=hrdb user=hr password=hr','select * from hr.demotable where 1=2') as t(num numeric,id integer);

insert into t_dblink
select * from dblink('hostaddr=127.0.0.1 port=5432 dbname=hrdb user=hr password=hr','select * from hr.demotable where id<1000') as t(num numeric,id integer);

explain analyze with t_temp as (select * from dblink('hostaddr=127.0.0.1 port=5432 dbname=hrdb user=hr password=hr','select * from hr.demotable where id<1000') as t(num numeric,id integer)) 
select a.num,a.id from t_dblink a,t_temp b where a.id=b.id;

使用dblink查询要带有conn_str,非常不简洁,可以考虑在会话使用临时表/视图来保存。

临时表调用方式

复制代码
postgres=# create temp table t_dblink as SELECT * FROM dblink('hostaddr=127.0.0.1 port=5432 dbname=hrdb user=hr password=hr','select * from hr.demotable') as t(num numeric,id integer);
SELECT 1000000
postgres=# select * from t_dblink;
...........

--退出后重新进去临时表不存在
postgres=# select * from t_dblink;
错误:  关系 "t_dblink" 不存在
第1行select * from t_dblink;

视图调用方式

如果认为每次查询都要写dblink的一堆信息很麻烦的话,可以在db中建一个view来解决

复制代码
postgres=# create view  v_dblink as SELECT * FROM dblink('hostaddr=127.0.0.1 port=5432 dbname=hrdb user=hr password=hr','select * from hr.demotable') as t(num numeric,id integer);
CREATE VIEW
postgres=# select * from v_dblink;
................
--退出后,重新执行
postgres=# select * from v_dblink;

到底选择视图/临时表,看你需求。在PostgreSQL中临时表在会话结束后是不会保持的,这样的好处:不使用的话无需去删除对应的临时表。

跨库执行ddl/dml操作

--如果需要跨库执行ddl、dml操作,使用dblink_exec

复制代码
SELECT dblink_connect('local_connect','hostaddr=127.0.0.1 port=5432 dbname=hrdb user=hr password=hr') as dev;
SELECT dblink_exec('local_connect', 'create table aa(id int,name varchar(50))');
SELECT dblink_exec('local_connect', 'drop table aa');
SELECT dblink_exec('local_connect', 'insert into hr.t values (1011102,8999,''hello'',''2048-10-09''::date)');
SELECT dblink_exec('local_connect', 'delete from  hr.t values where id=1011102');

总结

PostgreSQL使用这种dblink,存在优势是即取即用,无须在创建其他对象;劣势是只能连通posrgresql的不同数据库,不能进行异构数据库的连通。当然如果需要连接异构的数据库,可以使用Foreign Data Wrapper(FDW)插件,后面再来说说这个的使用方法。

关注我,学习更多的数据库知识!详情参考:PostgreSQL的dblink扩展模块使用方法

相关推荐
数据库学啊3 分钟前
时序数据库选型
数据库·时序数据库
TDengine (老段)4 分钟前
强杀服务、重启系统及断电对 TDengine 影响
运维·服务器·数据库·物联网·时序数据库·tdengine·涛思数据
数据库学啊6 分钟前
时序数据库怎么选
数据库·时序数据库
baivfhpwxf202318 分钟前
SQL Server 创建一个删除分表的作业,每月执行一次,删除表的逻辑放到存储过程里
数据库
不知更鸟5 小时前
Django 项目是什么
数据库·sqlite
有一个好名字8 小时前
MyBatis-Plus 三种数据库操作方式详解 + 常用方法大全
数据库·mybatis
-Xie-8 小时前
Redis(八)——多线程与单线程
java·数据库·redis
G探险者9 小时前
为什么 VARCHAR(1000) 存不了 1000 个汉字? —— 详解主流数据库“字段长度”的底层差异
数据库·后端·mysql
Albert Tan10 小时前
Oracle EBS R12.2.14 清理FND_LOBS并释放磁盘空间
数据库·oracle
L.EscaRC10 小时前
图数据库Neo4j原理与运用
数据库·oracle·neo4j