一、架构说明
同一宿主机运行两个 Oracle XE 21c 容器,通过 Docker 内网 + Oracle DBLINK 实现跨库联合查询。
oracle-db1:主查询库,宿主机端口1521oracle-db2:数据源库,宿主机端口1522- 限制:Oracle XE 单库数据上限 12GB,仅查询、不新建物理表,结果导出至本地。
二、配置Docker网络(容器互通)
bash
# 创建自定义网桥网络
docker network create orcl-network
# 将两个容器加入同一网络
docker network connect orcl-network oracle-db1
docker network connect orcl-network oracle-db2
查看 db2 容器内网IP
bash
docker inspect oracle-db2 | grep IPAddress
记录输出的内网 IP(例:172.17.0.5),后续配置使用。
三、创建 DBLINK 跨库连接
1. 登录 db1 业务用户
bash
docker exec -it oracle-db1 bash
sqlplus XZ_EHR/"Oracle123"@XEPDB1
2. 新建数据库链接
替换
172.17.0.5为实际查到的 db2 内网IP,端口固定使用容器内部1521
sql
-- 删除旧链路(存在时执行)
DROP DATABASE LINK link_db2;
-- 创建DBLINK(单行书写,避免语法报错)
CREATE DATABASE LINK link_db2
CONNECT TO XZ_EHR IDENTIFIED BY "Oracle123"
USING '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=172.17.0.5)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=XEPDB1)))';
3. 连通性测试
sql
SELECT 1 FROM DUAL@link_db2;
返回 1 代表跨库连接正常。
四、血脂相关数据跨库查询
最终查询 SQL
sql
SELECT DISTINCT
t1.CARDNO,t1.OP_EM_NO,t1.RPT_CAT_NAME,t1.RPT_CAT_CODE,
t2.NO_RPT,t2.SEX,t2.BIRTHDAY
FROM (
SELECT CARDNO,OP_EM_NO,RPT_CAT_NAME,RPT_CAT_CODE
FROM V_EMR_TEST_DOCUMENT_RECORD
WHERE RPT_CAT_NAME IN (
'血脂分析',
'甘油三酯',
'低密度脂蛋白胆固醇',
'高密度脂蛋白胆固醇'
))t1
INNER JOIN V_TEST_RESULT_RECORD@link_db2 t2
ON t1.CARDNO=t2.CARDNO AND t1.OP_EM_NO=t2.OP_EM_NO;
语句说明
- 数据源
V_EMR_TEST_DOCUMENT_RECORD:db1 检验项目视图V_TEST_RESULT_RECORD@link_db2:db2 患者信息视图,@link_db2表示访问远端库表
- 数据筛选:仅查询血脂类检验项目
- 关联条件:
CARDNO卡号 +OP_EM_NO就诊流水号
扩展用法
- 需保留 db1 全部数据(无匹配字段置空),将
INNER JOIN改为LEFT JOIN - 查询完成后,在客户端右键结果集,导出为 CSV/Excel 保存到本地。
五、常见问题处理
-
ORA-12543 目标主机不可达
容器未加入同一网络,重新执行
docker network connect命令。 -
ORA-01017/ORA-28000 密码错误/账号锁定
进入 db2 容器解锁并重置密码:
sqlALTER SESSION SET CONTAINER=XEPDB1; ALTER USER XZ_EHR ACCOUNT UNLOCK; ALTER USER XZ_EHR IDENTIFIED BY "Oracle123"; -
ORA-12954 超出12GB容量限制
XE 版本硬性容量限制,禁止执行建表语句,仅做查询并导出本地文件。
-
ORA-12533 TNS参数非法
DBLINK 中
USING后的地址串必须单行编写,不要换行、缩进。