一、Oracle环境准备
1. Windows虚拟机
2. Docker
sudo docker run -d --name oracle-test1 \ -p 1521:1521 -p 5500:5500 \ -e ORACLE_PWD=$PASSWD, \ container-registry.oracle.com/database/express:latest
# 2025-0410 最新版docker为oracle21c
# 连接到oracle数据库有两种方式
# 1. 安装客户端后使用sqlplus
# sqlplus system/($PASSWD),@localhost:1521/XE
# 2. 进docker bash环境 默认oracle用户为system,服务名XE,密码为命令行参数设置的。
sudo docker exec -it oracle-test1 bash sqlplus system/($PASSWD)@XE二、插件编译环境准备
1. Oracle客户端环境
https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html
# 根据要连接的oracle版本选择客户端版本,我这里使用的oracle版本是21c
mkdir -d /opt/oraClient
unzip -d /opt/oraClient instantclient-basic-linux.x64*
unzip -d /opt/oraClient instantclient-sdk-linux.x64*
unzip -d /opt/oraClient instantclient-sqlplus-linux.x64*
#确保存在libclntsh.so和libocci.so的软链接,不然编译oracle_fdw找不到
# cd /opt/oraClient/instantclient*
# ln -s libclntsh.so.12.1 libclntsh.so
# ln -s libocci.so.12.1 libocci.so
#客户端的so加到LD_LIBRARY_PATH
cd /etc/ld.so.conf.d/ vi oracle-x86_64.conf
##################################
/opt/oraClient/instantclient_21_17
##################################
sudo ldconfig2. pg环境
# 将插件的使用环境版本的pg路径加到环境变量中
export DB14_17_HOME=/usr/local/postgres/14.17
export PGPORT=5866
export PATH=$DB14_17_HOME/bin:$PATH
export PGDATA=$HOME/data注意部分版本不兼容:
Due to API breaks in PostgreSQL minor releases, the following PostgreSQL versions cannot be used:
- 9.6.0 to 9.6.8
- 10.0 to 10.3
- 11.0 to 11.10
- 12.0 to 12.5
- 13.0 to 13.9
- 14.0 to 14.6
- 15.0 to 15.1
三、编译
export ORACLE_HOME=/opt/oraClient/instantclient_21_17 make PG_CONFIG=$DB14_17_HOME/bin/pg_config sudo make PG_CONFIG=$DB14_17_HOME/bin/pg_config install可能遇到的问题,通常与pg版本不兼容,找不到客户端依赖头文件,依赖库有关
# pg版本不兼容
[postgres@localhost oracle_fdw-ORACLE_FDW_2_7_0]$ make gcc -std=gnu99 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -fPIC -I"/sdk/include" -I"/oci/include" -I"/rdbms/public" -I"/" -I. -I./ -I/home/highgo/HighGo4.5.6-see/include/postgresql/server -I/home/highgo/HighGo4.5.6-see/include/postgresql/internal -D_GNU_SOURCE -I/usr/include/libxml2 -c -o oracle_fdw.o oracle_fdw.c
oracle_fdw.c: In function ‘oracleBeginForeignInsert’:
oracle_fdw.c:1942:25: error: ‘ResultRelInfo’ has no member named ‘ri_RootResultRelInfo’ resultRelation = rinfo->ri_RootResultRelInfo->ri_RangeTableIndex;
^
make: *** [oracle_fdw.o] Error 1
[postgres@localhost oracle_fdw-ORACLE_FDW_2_7_0]$ vi ~/.bash_profile [postgres@localhost oracle_fdw-ORACLE_FDW_2_7_0]$ pg_config --version
PostgreSQL 12.1
[postgres@localhost oracle_fdw-ORACLE_FDW_2_7_0]$ postgres --version
postgres (PostgreSQL) 12.1
[postgres@localhost oracle_fdw-ORACLE_FDW_2_7_0]$ which postgres /home/highgo/HighGo4.5.6-see/bin/postgres四、创建插件,使用
这里设计的使用流程为:
- pg创建外部服务器和oracle用户映射,创建pg中对应oracle中表的外部表
- pg中查询oracle中的表
- pg向oracle中插入数据
- oracle中查询是否插入成功
-- oracle表 employees CREATE TABLE employees (
id NUMBER PRIMARY KEY,
name VARCHAR2(50),
salary NUMBER );
-- pg插入后,oracle查询
SELECT * FROM EMPLOYEES;
ID NAME SALARY
---------- -------------------- ----------
1 John Doe 50000-- postgres
create extension oracle_fdw;
-- 创建外部服务器
CREATE SERVER oracle_test_server
FOREIGN DATA WRAPPER oracle_fdw
OPTIONS (
dbserver '//localhost:1521/XE'
);
-- 创建用户映射,pg用户映射到oracle用户
CREATE USER MAPPING FOR CURRENT_USER
SERVER oracle_test_server
OPTIONS (
user 'system',
password '1qazWSX,'
);
-- 创建外部表
CREATE FOREIGN TABLE foreign_employees (
id INTEGER,
name VARCHAR(50),
salary NUMERIC
)
SERVER oracle_test_server
OPTIONS (
schema 'SYSTEM', -- Oracle 用户的 schema(默认是用户名大写)
table 'EMPLOYEES' -- Oracle 表名(需大写)
);
-- 查询外部表
SELECT * FROM foreign_employees;
-- 插入测试数据(如果 Oracle 用户有写权限)
INSERT INTO foreign_employees (id, name, salary)
VALUES (1, 'John Doe', 50000);