#创建测试远程库以及用户
create role remote login encrypted password 'remote';
CREATE DATABASE remote
WITH OWNER = postgres
TEMPLATE = template0
ENCODING = 'UTF8'
TABLESPACE = tbs_remote;
grant all on database remote to remote with grant option;
\c remote remote
create schema remote;
grant usage on schema remote to remote;
#在remote下创建测试表
\c remote remote
create table rmt_test (pk1 int, pk2 text, info text, crt_time timestamp(0), mod_time timestamp(0), primary key(pk1,pk2));
#建立server foreign data wrapper以及user mapping
\c local postgres
create extension postgres_fdw;
CREATE SERVER rmt FOREIGN DATA WRAPPER postgres_fdw OPTIONS (hostaddr 'xxxxxxxxx', port 'xxxx', dbname 'remote');
CREATE USER MAPPING FOR hank SERVER rmt OPTIONS (user 'remote', password 'remote');
GRANT USAGE ON FOREIGN SERVER rmt to hank;
#使用dblink(dblink_connect,dblink,dblink_disconnect,dblink_get_connections)
\c hank hank
select dblink_connect('hank','rmt');
select * from dblink('hank','select * from rmt_test') as tbl(a int,b text,c text, d timestamp without time zone,e timestamp without time zone) where a=6;
select dblink_disconnect('hank');
select dblink_get_connections();
dblink_get_connections
------------------------
{hank}
#使用dblink_exec(注意插入的字符字段要用两个单引号)
select dblink_connect('hank','rmt');
select * from dblink_exec('hank','insert into rmt_test(pk1,pk2) values (6,''dazuiba'');');
#这里fail_on_error参数也就是写true或者false的地方,做个比较,如果不写,默认是true,如果写false,那么会返回一个ERROR值
hank=> select * from dblink_exec('hank','insert into rmt_test(pk1,pk2) values (11,''today'');',true);
dblink_exec
-------------
INSERT 0 1
(1 row)
hank=> select * from dblink_exec('hank','insert into rmt_test(pk1,pk2) values (12,''tomorrow'');');
dblink_exec
-------------
INSERT 0 1
hank=> select * from dblink_exec('hank','insert into rmt_test(pk1,pk2) values (12,''tomorrow'');',false);
NOTICE: duplicate key value violates unique constraint "rmt_test_pkey"
DETAIL: Key (pk1, pk2)=(12, tomorrow) already exists.
CONTEXT: Error occurred on dblink connection named "hank": could not execute command.
dblink_exec
-------------
ERROR
(1 row)
#dblink cursor使用
#打开一个cursor
select * from dblink_open('hank','cursor1','select * from rmt_test');
#从cursor取出数据
select * from dblink_fetch('hank','cursor1',2) as (a int,b text,c text, d timestamp without time zone,e timestamp without time zone);
a | b | c | d | e
---+-----+-------------------------------+---------------------+---
1 | abc | 2016-05-09 16:11:57.138516+08 | 2016-05-09 16:11:57 |
2 | abc | 2016-05-09 16:11:57.138516+08 | 2016-05-09 16:11:57 |
(2 rows)
hank=> select * from dblink_fetch('hank','cursor1',2) as (a int,b text,c text, d timestamp without time zone,e timestamp without time zone);
a | b | c | d | e
---+-----+-------------------------------+---------------------+---
3 | abc | 2016-05-09 16:11:57.138516+08 | 2016-05-09 16:11:57 |
4 | abc | 2016-05-09 16:11:57.138516+08 | 2016-05-09 16:11:57 |
#关闭cursor
select * from dblink_close('hank','cursor1');
dblink_close
--------------
OK
#dblink_send_query,dblink_is_busy,dblink_error_message使用
#如果返回1则远程异步查询成功,否则返回0
hank=> SELECT * from dblink_send_query('hank','select pk1,pk2 from rmt_test where pk1<5') as t1;
t1
----
1
#
hank=> SELECT dblink_is_busy('hank');
dblink_is_busy
----------------
0
(1 row)
hank=> SELECT dblink_send_query('hank', 'select count(*) from rmt_test');
NOTICE: could not send query: another command is already in progress
dblink_send_query
-------------------
0
(1 row)
#获取最后一次错误
hank=> SELECT dblink_error_message('hank');
dblink_error_message
----------------------------------------
another command is already in progress+
#dblink_get_result获取查询的结果,这里返回pk1小于5的pk1,pk2字段
SELECT * FROM dblink_get_result('hank') AS t1(a int,b text);
a | b
---+-----
1 | abc
2 | abc
3 | abc
4 | abc
#取消远程异步查询
SELECT dblink_cancel_query('hank');
dblink_cancel_query
---------------------
OK
#dblink_get_pkey获取主键的位置,这里返回位置和列名
remote=> select * from dblink_get_pkey('rmt_test');
position | colname
----------+---------
1 | pk1
2 | pk2
#利用dlink函数生成各种dml语句
remote=> select * from rmt_test ;
pk1 | pk2 | info | crt_time | mod_time
-----+----------+-------------------------------+---------------------+----------
1 | abc | 2016-05-09 16:11:57.138516+08 | 2016-05-09 16:11:57 |
2 | abc | 2016-05-09 16:11:57.138516+08 | 2016-05-09 16:11:57 |
3 | abc | 2016-05-09 16:11:57.138516+08 | 2016-05-09 16:11:57 |
4 | abc | 2016-05-09 16:11:57.138516+08 | 2016-05-09 16:11:57 |
5 | abc | 2016-05-09 16:11:57.138516+08 | 2016-05-09 16:11:57 |
6 | dazuiba | | |
7 | apple | | |
11 | today | | |
12 | tomorrow | | |
#生成insert语句:
remote=> SELECT dblink_build_sql_insert('rmt_test', '1 2', 2, '{"7", "apple"}', '{"1", "abc"}');
dblink_build_sql_insert
---------------------------------------------------------------------------------------
INSERT INTO rmt_test(pk1,pk2,info,crt_time,mod_time) VALUES('1','abc',NULL,NULL,NULL)
#生成delete语句:
remote=> SELECT dblink_build_sql_delete('"rmt_test"', '1 2', 2, '{1, "dazuiba"}');
dblink_build_sql_delete
----------------------------------------------------------
DELETE FROM rmt_test WHERE pk1 = '1' AND pk2 = 'dazuiba'
#生成update语句:
remote=> SELECT dblink_build_sql_update('rmt_test', '1 2', 2, '{2,"abc"}', '{"7", "apple"}');
UPDATE rmt_test SET pk1 = '7', pk2 = 'apple', info = '2016-05-09 16:11:57.138516+08',
crt_time = '2016-05-09 16:11:57', mod_time = NULL WHERE pk1 = '7' AND pk2 = 'apple'
参考:http://www.postgresql.org/docs/9.5/static/dblink.html